|
| 1 | +.. _rfc140: |
| 2 | + |
| 3 | +================================================ |
| 4 | +MS RFC 140: MapServer Homepage |
| 5 | +================================================ |
| 6 | + |
| 7 | +:Author: Seth Girvin |
| 8 | + |
| 9 | +:Last Updated: 2025-01-18 |
| 10 | +:Version: MapServer 8.6 |
| 11 | +:Status: Draft |
| 12 | + |
| 13 | +1. Overview |
| 14 | +=========== |
| 15 | + |
| 16 | +This RFC proposes adding functionality to MapServer for dynamically generating a homepage that lists all map services available in a given deployment. |
| 17 | +This feature would enable the creation of pages like https://maps.isric.org/ directly from a MapServer deployment, without requiring |
| 18 | +additional scripting. While scripting can achieve this, integrating the capability into MapServer itself |
| 19 | +would offer greater convenience and maintainability. |
| 20 | + |
| 21 | +With the introduction of the :ref:`CONFIG file <config>` in MapServer 8.0, it is now possible to centrally manage information about all Mapfiles in a deployment. |
| 22 | +This would ensure that the homepage remains automatically synchronised with both the CONFIG file and the capabilities of the Mapfiles it references. |
| 23 | + |
| 24 | +2.1 Proposed Solution |
| 25 | +===================== |
| 26 | + |
| 27 | +A new MapServer :ref:`CGI mode <cgi>` - ``mode=config`` will be added to allow details of the MapServer services to be returned. The ``MAPS`` block |
| 28 | +in the :ref:`CONFIG file <config>` will be read to return a list of available services. By default the homepage service will be disabled unless a new |
| 29 | +``ENV`` option ``MS_HOMEPAGE_TEMPLATE`` has been set. This should be set to a folder containing a ``homepage.html`` value. However if only JSON |
| 30 | +responses are required it can be set to any value to enable the homepage service. |
| 31 | + |
| 32 | +.. code-block:: mapfile |
| 33 | + |
| 34 | + ENV |
| 35 | + MS_HOMEPAGE_TEMPLATE_DIRECTORY "share/ogcapi/templates/homepage/" # REQUIRED |
| 36 | + ... |
| 37 | + END |
| 38 | + # Example MAPS block in the CONFIG file |
| 39 | + MAPS |
| 40 | + TEST_MAPFILE1 "/opt/mapserver/test/test1.map" |
| 41 | + TEST_MAPFILE2 "/opt/mapserver/test/test2.map" |
| 42 | + END |
| 43 | + |
| 44 | +Users will be able to request the Mapfile details in two formats - HTML and JSON. A parameter can be added to the querystring to choose the format - |
| 45 | +it is proposed the OGC API use of the ``f`` parameter is |
| 46 | +used to select this, for example ``f=html`` or ``f=json``. As with the OGC Features API if not specified JSON will be the default. |
| 47 | +Requests will look as follows: |
| 48 | + |
| 49 | +.. code-block:: bat |
| 50 | + |
| 51 | + # example web requests |
| 52 | + # http://localhost/cgi-bin/mapserv.exe?mode=config&f=json |
| 53 | + # http://localhost/cgi-bin/mapserv.exe?mode=config&f=html |
| 54 | + |
| 55 | + # from the command line |
| 56 | + mapserv -nh "QUERY_STRING=mode=config&f=json" -conf "/usr/local/etc/mapserver.conf" |
| 57 | + mapserv -nh "QUERY_STRING=mode=config&f=html" -conf "C:\MapServer\apps\mapserver.conf" |
| 58 | + |
| 59 | +As the service returns JSON any client-side library can be used to render the output. However a default HTML template will be provided |
| 60 | +following the same approach as in OGC Features API. |
| 61 | + |
| 62 | +JSON Structure |
| 63 | +-------------- |
| 64 | + |
| 65 | +JSON will be generated using the nlohmann/json and Inja approach already implemented in :ref:`MS RFC 134: OGC API Support <rfc134>`. |
| 66 | +A proposed JSON structure is shown below. Final details may vary. URLs will be constructed based on settings in each individual Mapfile. |
| 67 | + |
| 68 | +.. code-block:: json |
| 69 | + |
| 70 | + { |
| 71 | + "id": "TEST_MAPFILE1", // the key in the config file |
| 72 | + "name": "My_Mapfile", // the NAME in the Mapfile |
| 73 | + "title": "My Mapfile Title", // the TITLE in the Mapfile |
| 74 | + "links": [ |
| 75 | + { |
| 76 | + "href": "https://demo.mapserver.org/cgi-bin/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities", |
| 77 | + "title": "GetCapabilities", |
| 78 | + "type": "WMS" |
| 79 | + }, |
| 80 | + { |
| 81 | + "href": "https://demo.mapserver.org/cgi-bin/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetCapabilities", |
| 82 | + "title": "GetCapabilities", |
| 83 | + "type": "WFS" |
| 84 | + }, |
| 85 | + { |
| 86 | + "href": "https://demo.mapserver.org/cgi-bin/wcs?SERVICE=WCS&VERSION=1.0.0&REQUEST=GetCapabilities", |
| 87 | + "title": "GetCapabilities", |
| 88 | + "type": "WCS" |
| 89 | + }, |
| 90 | + { |
| 91 | + "href": "https://demo.mapserver.org/cgi-bin/mapserv/localdemo/ogcapi/api?f=html", |
| 92 | + "title": "Landing Page", |
| 93 | + "type": "OGCAPI" |
| 94 | + }, |
| 95 | + ] |
| 96 | + } |
| 97 | + |
| 98 | + |
| 99 | +Future Development |
| 100 | +------------------ |
| 101 | + |
| 102 | +Once the general approach is in place more details could be added to this structure, such as the EXTENT and default PROJECTION. |
| 103 | +The OGC Features API JSON can be used as a guide to create the structure, for example for the extent: |
| 104 | + |
| 105 | +.. code-block:: json |
| 106 | + |
| 107 | + "extent": { |
| 108 | + "spatial": { |
| 109 | + "bbox": [ |
| 110 | + [ |
| 111 | + -180, |
| 112 | + -90, |
| 113 | + 180, |
| 114 | + 90 |
| 115 | + ] |
| 116 | + ], |
| 117 | + "crs": "http://www.opengis.net/def/crs/OGC/1.3/CRS84" |
| 118 | + } |
| 119 | + }, |
| 120 | + |
| 121 | +It may be beneficial to allow an administrator to choose what data is made available through the service. A similar approach to |
| 122 | +the use of ``ows_enable_request`` could be considered. Additional links could include the OpenLayers Map (see :ref:`rfc63`). |
| 123 | + |
| 124 | +Potentially the approach taken in this RFC could be used to return the same information for a single Mapfile, providing individual home pages |
| 125 | +for each Mapfile. |
| 126 | + |
| 127 | +2.2 Limitations |
| 128 | +=============== |
| 129 | + |
| 130 | +Mapfiles will need to be listed in the ``MAPS`` block of the ``CONFIG`` file to be listed as part of the service. |
| 131 | +There will be no support for reading all Mapfiles in a folder - this would be best handled by scripting the MAPS section of the |
| 132 | +CONFIG file. |
| 133 | + |
| 134 | +Available services such as WMS, WFS etc. will be checked for using the ``ows_enable_request`` in the ``METADATA`` section of a Mapfile, however there is no guarantee |
| 135 | +that the URLs will return valid XML if the Mapfile is not configured correctly. |
| 136 | + |
| 137 | +2.3 Testing |
| 138 | +=========== |
| 139 | + |
| 140 | +``msautotests`` will be added to validate various CONFIG and Mapfile setups. |
| 141 | + |
| 142 | +2.4 Security Concerns |
| 143 | +===================== |
| 144 | + |
| 145 | +This new feature will make services more discoverable, but with this comes the risk of leaking information. |
| 146 | +The service will be opt-in, and up to the administrators of the deployment if they want this information to be |
| 147 | +visible by setting the ``MS_HOMEPAGE_TEMPLATE_DIRECTORY`` value in the ``CONFIG`` file. |
| 148 | + |
| 149 | +2.5 MapScript |
| 150 | +============= |
| 151 | + |
| 152 | +It is not planned to add MapScript support for this RFC. |
| 153 | +None of the current MapServer ``mode`` functionality is supported in MapScript, nor the OGC Features API functions. |
| 154 | + |
| 155 | +3. Implementation Details |
| 156 | +========================= |
| 157 | + |
| 158 | +This section contains notes from prototyping a possible solution. The final approach may differ. |
| 159 | + |
| 160 | +A requests will be checked for ``mode=config`` in mapserv.c to return JSON and exit. |
| 161 | +A new mode will be added to ``mapservutil.c`` |
| 162 | + |
| 163 | +.. code-block:: c |
| 164 | + |
| 165 | + static char *const modeStrings[23] |
| 166 | + |
| 167 | +To list services supported in a Mapfile ``msOWSRequestIsEnabled`` will be used: |
| 168 | + |
| 169 | +- "AO", "OGCAPI" |
| 170 | +- "M", "GetMap", "GetCapabilities" |
| 171 | +- "F" (WFS) "GetCapabilities" |
| 172 | +- "CO" "GetCapabilities" |
| 173 | + |
| 174 | +Example ``int status = msOWSRequestIsEnabled(map, NULL, "AO", "OGCAPI", MS_FALSE);`` |
| 175 | + |
| 176 | +For constructing URLs ``msOWSGetOnlineResource`` will be used (which calls ``msBuildOnlineResource`` |
| 177 | +if ``ows_onlineresource`` (or ``wms_``, ``wfs_`` etc.) is not set. |
| 178 | + |
| 179 | +3.1 Affected files |
| 180 | +------------------ |
| 181 | + |
| 182 | ++ mapserv.c |
| 183 | ++ mapservutil.c |
| 184 | ++ mapserver.h |
| 185 | + |
| 186 | +3.2 Ticket Reference |
| 187 | +-------------------- |
| 188 | + |
| 189 | ++ TODO |
| 190 | + |
| 191 | +3.3 Documentation |
| 192 | +----------------- |
| 193 | + |
| 194 | +TODO |
| 195 | + |
| 196 | +4. Voting History |
| 197 | +================= |
0 commit comments