MapServer / mapcache

MapCache source code directory. Please submit pull requests to the 'main' branch.
https://mapserver.org/mapcache
Other
137 stars 96 forks source link

HTTP OPTIONS Request to getcababilities throws a 405 error #268

Open LieGeo opened 2 years ago

LieGeo commented 2 years ago

Google Chrome calls the GETCAPABILITIES request as HTTP OPTIONS request in our Geoportal-application. mapchache delivers a 405 Issue to this request

Example: curl -X OPTIONS https://path.to.server/mapcache/wmts?SERVICE=WMTS&REQUEST=getcapabilities -i

Response from mapache:

_<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

405 Method Not Allowed

Method Not Allowed

The requested method OPTIONS is not allowed for this URL.

_ I don't know why Google Chrome uses the HTTP OPTIONS in header, but it does. Our applications stops with error 405. Other browsers seem to work without any problems. Is there a configuration option to configure OPTIONS requests? Regards Peter
sdlime commented 2 years ago

Might be worth taking this to the mapserver-users or mapserver-dev list - more eyes...

jbo-ads commented 2 years ago

@sdlime : Good advice, I am not familiar enough with HTTP to provide a useful answer.

@LieGeo : I don't think such a configuration option exists in MapCache. What do you think should be a correct response to this HTTP OPTIONS request?

LieGeo commented 2 years ago

I don't think that the response is so important.

Important seems to bee an response header with HTTP Code 200 ( not 405) and maybe the OPTIONS header This is what Mapserver does. See example below

curl -X OPTIONS "https://path.to.server/mapserver/mymap?service=WMS&request=GetCapabilities" -i

HTTP/1.1 200 OK Date: Tue, 12 Oct 2021 14:33:21 GMT Access-Control-Allow-Origin: * X-Via-NSCOPI: 1.0 Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 Content-Language: de Set-Cookie: NSC_ESNS=041cfbb6-9cec-1165-9678-42365d735168_3719986305_2914007603_00000000004363009958; Path=/; Expires=Tue, 12-Oct-2021 14:33:36 GMT Cache-Control: no-cache Strict-Transport-Security: max-age=15552000; includeSubDomains

This script should be referenced with a METHOD of GET or METHOD of POST.

jratike80 commented 2 years ago

I believe that the supported http methods are configured with your web server. I have found documents about how to disable OPTIONS method that is considered to be some kind of security issue. I used the recipe from https://support.cpanel.net/hc/en-us/articles/360057430513-How-To-disable-http-OPTIONS-method-in-Apache- and made a trial with MS4W. I edited the Apache httpd.conf like this

#
# Configure MS4W locations and directories
#
<Location "/cgi-bin">
    Options None
    <LimitExcept GET POST>
            order deny,allow
            deny from all
    </LimitExcept>
    Require all granted
</Location>

After restart curl -X OPTIONS leads into this:

curl -X OPTIONS http://localhost:8060/cgi-bin/mapserv.exe -i|more
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   199  100   199    0     0   7960      0 --:--:-- --:--:-- --:--:--  8291
HTTP/1.1 403 Forbidden
Date: Tue, 12 Oct 2021 15:25:20 GMT
Server: Apache/2.4.46 (Win32) mod_fcgid/2.3.9 mod-mapcache/1.11dev mod_wsgi/4.7.1 Python/3.9
Content-Length: 199
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>

So I could change Mapserver to behave about in the same way than MapCache does for you. From all that I read from the web I got a feeling that web servers do not need to support OPTIONS and code 405 is probably the best response then https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405.

My conclusions: if you want to support OPTIONS method with the web server on which you are running MapCache, study how to configure that web server. And generally no client should rely on that OPTIONS is supported because usually it is not. I tried with a bunch of sites and 405 was the most common result. Try for example with google.com.

jmckenna commented 2 years ago

Thanks for the research @jratike80, I'm going to add this note to the MS4W readme for the next release (ticket: https://ms4w.com/trac/ticket/351).

LieGeo commented 2 years ago

I tried to configure Apache to anwser the OPTIONS request to mapache, but until know without success. Apache has an option AllowMethods, but adding this option to /cgi-bin and /ms4w/mapcache/ did not work AllowMethods GET POST OPTIONS

In addition, there seems to be a useful reason to make an OPTIONS request in the sense of a CORS preflight. Chrome seems to check the CORS configuration before calling capabiities-URL request. This seems reasonable, which meens, we should support OPTIONS Request. How can this configured in Apache if not in the application code itself?

jratike80 commented 2 years ago

I think now that configuring http server is not enough. The accepted methods seem to be hardcoded into https://github.com/MapServer/mapcache/blob/447c0c6848fd101c11e6d54e451037e571117ef1/apache/mod_mapcache.c

if((l=mapcache_alias_matches(r->uri, alias_entry->endpoint))>0) {
      if (r->method_number != M_GET && r->method_number != M_POST) {
        return HTTP_METHOD_NOT_ALLOWED;

Your description of the problem is that Chrome cannot read GetCapabilities from MapCache because it automatically adds the OPTIONS header and it requires that the server supports OPTIONS method. If server does not allow OPTIONS and sends the 405 response, that is right according to the http standard, then Crome can not read GetCapabilities. This seems to mean that most MapCache installations will not work with Chrome. And because supporting OPTIONS is by no means compulsory, that feels odd.

What is your Chrome version? I have version 94.0.4606.71 and I made the following test:

It works, but I was reading that Chrome 79 has some changes on this area https://httptoolkit.tech/blog/chrome-79-doesnt-show-cors-preflight/ so perhaps my Chrome is just too old for showing the issue.

yfr commented 2 years ago

I think the OPTIONS request is quite important.

With an OPTIONS request the client asks the server which requests are allowed. Which methods are allowed and if the client should even attempt to send the full request.

It's also vitally important for CORS requests. Most of the browser should send a preflight request before sending the real request, which is an OPTIONS request that asks for CORS settings (more info about CORS in this recent article: https://jakearchibald.com/2021/cors/).

We had a similar problem like OP. Our MapCache runs in a docker container (https://github.com/camptocamp/docker-mapcache) and we could not get the requests through to the server.

We extended the Dockerfile with:

RUN a2enmod headers
COPY cors.conf /etc/apache2/conf-enabled/

This enables the apache headers module and copies the apache CORS configuration into the container.

This is how the cors.conf config looks like:

RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L]

Header always set Access-Control-Allow-Origin "*"                   
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"

I'm not a not sure about all the details of HTTP request methods but, I know that without a valid OPTIONS response most browser refuse to make the full request. Even though they are not manatory.