1

Setup: a QGis-2.18 Server (really an embedded MapServer) instance via FastCGI in Apache-2.4.18 on Ubuntu.

If a certain value is set in the query string for the cgi handler, I would like to add another value. To that end, I have added three lines to the top of /etc/apache2/conf-enabled/qgis.conf:

RewriteEngine on
RewriteCond "%{QUERY_STRING}" "application/json" [NC]
RewriteRule "^/$" "/?OUTPUTFORMAT=GeoJSON" [PT,QSA]

ScriptAlias / /usr/lib/cgi-bin/qgis_mapserv.fcgi
<Location "/">
    SetHandler fcgid-script
    Require all granted
    PassEnv QGIS_PROJECT_FILE
</Location>

FcgidInitialEnv QGIS_LOG_FILE ${QGIS_LOG_FILE}
FcgidInitialEnv QGIS_SERVER_LOG_FILE ${QGIS_SERVER_LOG_FILE}
FcgidInitialEnv QGIS_DEBUG ${QGIS_DEBUG}
FcgidInitialEnv QGIS_SERVER_LOG_LEVEL ${QGIS_SERVER_LOG_LEVEL}
FcgidInitialEnv QGIS_PLUGINPATH "${QGIS_PLUGINPATH}"
FcgidInitialEnv PGSERVICEFILE ${PGSERVICEFILE}
FcgidInitialEnv HOME /var/www

I'm accessing the server like this:

http://myserver.invalid.tld:51081/
    ?SERVICE=WFS
    &VERSION=1.1.0
    &REQUEST=GetFeature
    &OUTPUTFORMAT=application/json
    &MAXFEATURES=1
    &SRSNAME=EPSG:4326
    &TYPENAME=feature_type_name
    &BBOX=8.5985658,56.447691,8.600106,56.448553

I would have expected the effect to be the same as if I had manually appended &OUTPUTFORMAT=GeoJSON at the end of my URL, but I see no difference at all after restarting apache. (Yes, I have run sudo a2enmod rewrite.)

I am unsure how the interaction between rewrite rules and a script alias works, so I'm thinking that one shadows the other? Unfortunately, I also have no idea how to debug this.

The server has one virtual host enabled, which looks like OOTB config to me:

# apache2ctl -S
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.10. Set the 'ServerName' directive globally to suppress this message
VirtualHost configuration:
*:80                   172.17.0.10 (/etc/apache2/sites-enabled/000-default.conf:1)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/proc/self/fd/2"
Mutex default: dir="/var/lock/apache2" mechanism=fcntl
Mutex fcgid-pipe: using_defaults
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: using_defaults
Mutex fcgid-proctbl: using_defaults
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33
Group: name="www-data" id=33 

Here's /etc/apache2/sites-enabled/000-default.conf (comments stripped):

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog /proc/self/fd/2
    CustomLog /proc/self/fd/1 combined
</VirtualHost>

And finally apache2.conf (again, comments stripped):

Mutex file:${APACHE_LOCK_DIR} default
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
ErrorLog /proc/self/fd/2
LogLevel warn

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
Include ports.conf

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

AccessFileName .htaccess

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

(For bonus points I'd like to replace application/json in the query string with GeoJSON, but if I could get the parameter appended to begin with I'm close to the goal.)

kthy
  • 113
  • 5

1 Answers1

1

I would have expected the effect to be the same as if I had manually appended &OUTPUTFORMAT=GeoJSON

Well, that maybe the "problem"; it's not appended. The original query string on the request is appended. The query string (OUTPUTFORMAT=GeoJSON) in the substitution string is at the start of the query string. So, depending on how you are reading/parsing the parameters in the query string, your new setting is probably being overwritten.

To specifically append something to the existing query string you can make use of the QUERY_STRING server variable in the substitution (instead of using the QSA flag). For example:

RewriteCond %{QUERY_STRING} application/json
RewriteRule ^/$ /?%{QUERY_STRING}&OUTPUTFORMAT=GeoJSON [PT]

No need to wrap every argument in quotes, unless they contain spaces. Only use the NC flag if you specifically need a case-insensitive match.

Alternatively, to replace the OUTPUTFORMAT=application/json URL parameter in the request, then you can do something like this:

RewriteCond %{QUERY_STRING} (.*)OUTPUTFORMAT=application/json(.*)
RewriteRule ^/$ /?%1OUTPUTFORMAT=GeoJSON%2 [PT]

%1 and %2 are backreferences to the captured groups in the preceding CondPattern. ie. Everything before and after the original URL parameter in the query string.

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • 1
    Thanks for pointing out that I had misread the docs on what `[QSA]` does! :o) Your rewriterule with the back references worked like a charm, once we had found the right place to put it. Thanks a bunch. – kthy Oct 24 '17 at 08:36