Skip to content

Commit

Permalink
Support for a mapserv config file. (#6303)
Browse files Browse the repository at this point in the history
Adds support for a MapServer configuration file. It is required for CGI use and optional for MapScript. It standardizes site-level configuration across various operating system and web servers.

Co-authored-by: sethg <sethg@geographika.co.uk>
Co-authored-by: Even Rouault <even.rouault@spatialys.com>
  • Loading branch information
3 people committed Oct 25, 2021
1 parent 67b1f04 commit f478a37
Show file tree
Hide file tree
Showing 36 changed files with 3,234 additions and 2,620 deletions.
63 changes: 56 additions & 7 deletions .github/workflows/start.sh
Expand Up @@ -69,6 +69,9 @@ cat <<EOF >/etc/apache2/sites-available/001-mapserver.conf
ErrorLog \${APACHE_LOG_DIR}/mapserv-error.log
CustomLog \${APACHE_LOG_DIR}/mapserv-access.log combined
SetEnv MAPSERVER_CONFIG_FILE ${WORK_DIR}/msautotest/etc/mapserv.conf
FcgidInitialEnv MAPSERVER_CONFIG_FILE ${WORK_DIR}/msautotest/etc/mapserv.conf
ScriptAlias /cgi-bin/ "/tmp/install-mapserver/bin/"
<Directory "/tmp/install-mapserver/bin">
AddHandler fcgid-script .fcgi
Expand Down Expand Up @@ -107,28 +110,74 @@ cd msautotest/wxs

export PATH=/tmp/install-mapserver/bin:$PATH

# Demonstrate that mapserv will error out if cannot find config file
mapserv 2>&1 | grep "msLoadConfig(): Unable to access file" >/dev/null && echo yes
mapserv QUERY_STRING="MAP=wfs_simple.map&REQUEST=GetCapabilities" 2>&1 | grep "msLoadConfig(): Unable to access file" >/dev/null && echo yes

echo "Check that MS_MAP_NO_PATH works"
MS_MAP_NO_PATH=1 MYMAPFILE=wfs_simple.map mapserv QUERY_STRING="MAP=MYMAPFILE&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat <<EOF >/tmp/mapserver.conf
CONFIG
ENV
"MS_MAP_NO_PATH" "1"
END
MAPS
"MYMAPFILE" "wfs_simple.map"
END
END
EOF
# Also demonstrate that mapserv can find config file in ${CMAKE_INSTALL_FULL_SYSCONFDIR}/etc/mapserver.conf by default
ln -s /tmp/mapserver.conf /tmp/install-mapserver/etc
mapserv QUERY_STRING="MAP=MYMAPFILE&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
rm /tmp/install-mapserver/etc/mapserver.conf
cat /tmp/res.txt | grep wfs:WFS_Capabilities >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Check that MS_MAP_NO_PATH cannot be abused with client-controlled env variables"
MS_MAP_NO_PATH=1 CONTENT_TYPE=wfs_simple.map mapserv QUERY_STRING="MAP=CONTENT_TYPE&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
echo "Check that MS_MAP_NO_PATH works (rejecting a value not defined in the MAPS section)"
MAPSERVER_CONFIG_FILE=/tmp/mapserver.conf mapserv QUERY_STRING="MAP=FOO&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat /tmp/res.txt | grep "Web application error" >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Check that MS_MAP_PATTERN works (accepting valid MAP)"
MS_MAP_PATTERN="^wfs_simple\.map$" mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat <<EOF >/tmp/mapserver.conf
CONFIG
ENV
"MS_MAP_PATTERN" "^wfs_simple\.map$"
END
END
EOF
MAPSERVER_CONFIG_FILE=/tmp/mapserver.conf mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat /tmp/res.txt | grep wfs:WFS_Capabilities >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Check that MS_MAP_PATTERN works (rejecting invalid MAP)"
MS_MAP_PATTERN=mypatternmapserv mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat <<EOF >/tmp/mapserver.conf
CONFIG
ENV
"MS_MAP_PATTERN" "mypatternmapserv"
END
END
EOF
MAPSERVER_CONFIG_FILE=/tmp/mapserver.conf mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat /tmp/res.txt | grep "Web application error" >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Check that MS_MAPFILE works alone"
MS_MAPFILE=wfs_simple.map mapserv QUERY_STRING="SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat <<EOF >/tmp/mapserver.conf
CONFIG
ENV
"MS_MAPFILE" "wfs_simple.map"
END
END
EOF
MAPSERVER_CONFIG_FILE=/tmp/mapserver.conf mapserv QUERY_STRING="SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat /tmp/res.txt | grep wfs:WFS_Capabilities >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Check that a MAP query parameter isn't accepted when MS_MAPFILE and MS_MAP_NO_PATH are specified"
MS_MAP_NO_PATH=1 MS_MAPFILE=wfs_simple.map mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat <<EOF >/tmp/mapserver.conf
CONFIG
ENV
"MS_MAPFILE" "wfs_simple.map"
"MS_MAP_NO_PATH" "1"
END
END
EOF
MAPSERVER_CONFIG_FILE=/tmp/mapserver.conf mapserv QUERY_STRING="MAP=wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.txt
cat /tmp/res.txt | grep "Web application error" >/dev/null || (cat /tmp/res.txt && /bin/false)

echo "Done !"
15 changes: 13 additions & 2 deletions CMakeLists.txt
Expand Up @@ -291,7 +291,7 @@ mapgeomtransform.c mapogroutput.cpp mapwfslayer.c mapagg.cpp mapkml.cpp
mapgeomutil.cpp mapkmlrenderer.cpp fontcache.c textlayout.c maputfgrid.cpp
mapogr.cpp mapcontour.c mapsmoothing.c mapv8.cpp ${REGEX_SOURCES} kerneldensity.c
idw.c interpolation.c
mapcompositingfilter.c mapmvt.c mapiconv.c mapgraph.cpp)
mapcompositingfilter.c mapmvt.c mapiconv.c mapgraph.cpp mapserv-config.cpp)

set(mapserver_HEADERS
cgiutil.h dejavu-sans-condensed.h dxfcolor.h fontcache.h hittest.h mapagg.h
Expand All @@ -300,7 +300,7 @@ maphttp.h mapio.h mapkmlrenderer.h maplibxml2.h mapogcfilter.h mapogcsld.h
mapoglcontext.h mapoglrenderer.h mapowscommon.h mapows.h mapparser.h mapogcapi.h
mappostgis.h mapprimitive.h mapproject.h mapraster.h mapregex.h mapresample.h
mapserver-api.h mapserver.h mapserv.h mapshape.h mapsymbol.h maptemplate.h
mapthread.h maptile.h maptime.h maptree.h maputfgrid.h mapwcs.h uthash.h mapiconv.h mapgraph.h)
mapthread.h maptile.h maptime.h maptree.h maputfgrid.h mapwcs.h uthash.h mapiconv.h mapgraph.h mapserv-config.h)

if(WIN32)
configure_file(
Expand Down Expand Up @@ -1049,16 +1049,22 @@ if(UNIX)
else()
set(DEFAULT_DATA_SUBDIR share/mapserver)
endif()
set(DEFAULT_CONFIG_FILE ${CMAKE_INSTALL_FULL_SYSCONFDIR}/mapserver.conf)

# Locations are changeable by user to customize layout of MapServer installation
# (default values are platform-specific)
set(MAPSERVER_DATA_SUBDIR ${DEFAULT_DATA_SUBDIR} CACHE STRING
"Subdirectory where data will be installed")

set(MAPSERVER_CONFIG_FILE "${DEFAULT_CONFIG_FILE}" CACHE STRING
"Full file name for default configuration file (mapserver.conf)")

# Mark *DIR variables as advanced and dedicated to use by power-users only.
mark_as_advanced(
MAPSERVER_DATA_SUBDIR
MAPSERVER_CONFIG_FILE
)
add_definitions(-DMAPSERVER_CONFIG_FILE="${MAPSERVER_CONFIG_FILE}")

install(
FILES ${PROJECT_SOURCE_DIR}/share/ogcapi/templates/html-plain/collection.html
Expand All @@ -1073,3 +1079,8 @@ install(
${PROJECT_SOURCE_DIR}/share/ogcapi/templates/html-plain/openapi.html
DESTINATION ${MAPSERVER_DATA_SUBDIR}/ogcapi/templates/html-plain/
)

install(
FILES ${PROJECT_SOURCE_DIR}/etc/mapserver-sample.conf
DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/
)
4 changes: 3 additions & 1 deletion cgiutil.c
Expand Up @@ -36,6 +36,8 @@
#include "mapserver.h"
#include "cgiutil.h"

#include "cpl_conv.h"

#define LF 10
#define CR 13

Expand Down Expand Up @@ -142,7 +144,7 @@ int loadParams(cgiRequestObj *request,

debuglevel = (int)msGetGlobalDebugLevel();

if(strcmp(getenv2("REQUEST_METHOD", thread_context),"POST") == 0) { /* we've got a post from a form */
if(strcmp(getenv2("REQUEST_METHOD", thread_context),"POST") == 0 && CPLGetConfigOption("MS_NO_POST", NULL) == NULL) { /* we've got a post from a form */
char *post_data;
int data_len;
request->type = MS_POST_REQUEST;
Expand Down
64 changes: 64 additions & 0 deletions etc/mapserver-sample.conf
@@ -0,0 +1,64 @@
#
# Sample MapServer 8.0 Config File
#
CONFIG

#
# Environment variables (see https://mapserver.org/environment_variables.html)
#
ENV
#
# Limit Mapfile Access
#
# MS_MAP_NO_PATH "1"
MS_MAP_PATTERN "^/opt/mapserver" ## required

#
# Global Log/Debug Setup
#
# MS_DEBUGLEVEL "5"
# MS_ERRORFILE "/opt/mapserver/logs/mapserver.log"

#
# Default Map
#
# MS_MAPFILE "/opt/mapserver/test/test.map"

#
# Proj Library
#
# PROJ_LIB ""

#
# Request Control
#
# disable POST requests (allowed by default, any value will do)
# MS_NO_POST "1"

#
# Other Options
#
# MS_ENCRYPTION_KEY
# MS_USE_GLOBAL_FT_CACHE
# MS_PDF_CREATION_DATE
# MS_MAPFILE_PATTERN "\.map$"
# MS_XMLMAPFILE_XSLT
# MS_MODE
# MS_OPENLAYERS_JS_URL
# MS_TEMPPATH
# MS_MAX_OPEN_FILES

#
# OGC API
#
# OGCAPI_HTML_TEMPLATE_DIRECTORY "/usr/local/mapserver/share/ogcapi/templates/html-bootstrap4/"
END

#
# Map Aliases
#
MAPS
# TEST_MAPFILE "/opt/mapserver/test/test.map"
END

END
4 changes: 3 additions & 1 deletion fontcache.c
Expand Up @@ -32,6 +32,8 @@
#include "fontcache.h"
#include "dejavu-sans-condensed.h"

#include "cpl_conv.h"

typedef struct {
FT_Library library;
face_element *face_cache;
Expand Down Expand Up @@ -160,7 +162,7 @@ void msFontCacheSetup() {
ft_cache *c = msGetFontCache();
msInitFontCache(c);
#else
char* use_global_cache = getenv("MS_USE_GLOBAL_FT_CACHE");
const char *use_global_cache = CPLGetConfigOption("MS_USE_GLOBAL_FT_CACHE", NULL);
if (use_global_cache)
use_global_ft_cache = atoi(use_global_cache);
else
Expand Down
2 changes: 1 addition & 1 deletion legend.c
Expand Up @@ -47,7 +47,7 @@ int main(int argc, char *argv[])
exit(0);
}

map = msLoadMap(argv[1], NULL);
map = msLoadMap(argv[1], NULL, NULL);
if(!map) {
msWriteError(stderr);
exit(0);
Expand Down

0 comments on commit f478a37

Please sign in to comment.