Skip to content

nginx locations not ending with / (slash) generates http 301 (redirection) with port #630

@matthieumarrast

Description

@matthieumarrast

Problem

If you install a static plugin then try to access the plugin's uri without trailing slash http://localhost:18868/foo, the server returns an HTTP 301 (redirect) with url http://localhost:18868/foo/ (trailing slash added). Locally it's OK.

But if you are behind a reverse proxy "hiding" the local port, accessing http://yourwebsite/foo will redirect to http://yourwebsite:18868/foo/
so it

  1. leaks the internal port
  2. breaks the redirection

Analysis

From http://nginx.org/en/docs/http/ngx_http_core_module.html#location
If a location is defined by a prefix string that ends with the slash character, [...] the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended.

The location in our nginx configuration is:

# if you don't understand (?:/(.*))?, read https://serverfault.com/a/476368
location ~ ^/foo(?:/(.*))?$ {
    error_page 599 /invalid; # this http code (599) does not exist but we need this line to avoid HTTP/404 capture by welcome plugin (see nginx docs)
    alias /home/mfserv/var/plugins/foo/main/$1;
    set $plugin "foo";
}

maybe I "don't understand" the pattern (?:/(.*))?$ (handling trailing slash or not) but it is probably the cause of the nginx redirection : /foo matches the path ^/foo(?:/(.*))?$, so "a permanent redirect with the code 301 will be returned to the requested URI with the slash appended".

Workaround/Solution

  • 1 "leaks the internal port":
    To avoid having the port in redirection, we can add the port_in_redirect off; directive in the nginx configuration.
    It will be added soon as port_in_redirect=1 in the mfserv config.ini, cf. add support of the nginx port_in_redirect directive #625

  • 2 "breaks the redirection": removing the port from the redirection (solution 1) will solve the issue... but we'll still have an HTTP 301 redirect. If you really want to avoid the http 301 redirect I do not have a solution for now... any proposal is accepted

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions