Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I match any path containing a dot with nginx?

I am trying to implement a proxy using the nginx configuration

The idea is to have a http server hosting my website (my SPA). and having one route on my http server pointing to another api.

this is my nginw configuration file below

client_max_body_size 100M;

server {
    listen       80;
    server_name  localhost;

    root   /usr/share/nginx/html;
    index  index.html index.htm;

    location ^~ /proxyapi/ {
        proxy_read_timeout 180s;
        proxy_send_timeout 180s;
        proxy_pass http://localhost:5000/;
    }

    location ~* /static/* {
      try_files $uri =404;
      expires 1y;
      access_log off;
      add_header Cache-Control "public";
    }

    # Any route that doesn't have a file extension (e.g. /devices)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

it works fine most of the time

when I call http://my-nginx-host/proxyapi/search/login, it works...

unless there is a dot in the login

http://my-nginx-host/proxyapi/search/login => works fine

http://my-nginx-host/proxyapi/search/log.in => fails with a "404 resource not found"

is there any way to make it work? I couldn't find any solution

like image 549
netlyonel Avatar asked May 27 '19 16:05

netlyonel


People also ask

How does nginx match location?

To find a location match for an URI, NGINX first scans the locations that is defined using the prefix strings (without regular expression). Thereafter, the location with regular expressions are checked in order of their declaration in the configuration file.

What regex does nginx use?

NGINX uses Perl Compatible Regular Expressions (PCRE), and this post assumes a basic understanding of both NGINX and regular expressions. Explaining how to construct regexes is outside the scope of this post, and we regret that we cannot answer further questions in the comments section about how to do so.

What is nginx prefix path?

–prefix=*path*defines a directory that will keep server files. This same directory will also be used for all relative paths set by configure (except for paths to libraries sources) and in the nginx. conf configuration file. It is set to the /usr/local/nginx directory by default.

Where is nginx file path?

Every NGINX configuration file will be found in the /etc/nginx/ directory, with the main configuration file located in /etc/nginx/nginx. conf .


1 Answers

Matching any dot in URI can be done with this:

location ~* \..*$ {
 # try_files $uri $uri/ =404;
 # ...
}

Let's take the regex apart:

  • ~* Tells nginx to do case-insensitive regex matching (~ for case-sensitive)
  • \. Matches to literal dot symbol .
  • .* The dot here equals to any symbol except whitespace, asterisk modifies the preceding symbol to "match as many of this as possible"
  • $ Matches end of line

You can use this regex if you want to match even "malformed" uris like log.in

EDIT: In your situation, you would have to place this regex after your location ~* /static/* so it won't match uris with dots like /static/image.png. See notes for explanation.


Notes

Take in mind this location block will match any dot anywhere in passed URI. So it will match URIs like these /a.ssets/images/, /assets/favicon.ico too. Any non-terminating locations (ones without ^~ or =) will not be used even if they should match, if the dot regex matches and it's first matching regex location it takes precedence over anything else.

Important snippet from nginx's docs about matching preference of location:

Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

like image 171
Wereii Avatar answered Sep 30 '22 14:09

Wereii