2

I'm trying to set up a location such that suffix /reset_password/any_text would load index.html from the directory specified in the alias. Unfortunately, with no luck...

# location /reset_password { # alias /var/www/grades-ui; # } location /reset_password/([0-9a-z]*) { alias /var/www/grades-ui; } 

The commented out code works fine to load exact path /reset_password, however my goal is to serve /reset_password/any_text_or_number.

Any ideas why my regular expression wouldn't work? Or maybe I'm doing something else completely wrong?

Edit: the complete conf file

server { listen 443 ssl; # managed by Certbot root /var/www/grades-ui; server_name www.mygrades.co.uk mygrades.co.uk; ssl_certificate /etc/letsencrypt/live/mygrades.co.uk/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mygrades.co.uk/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot location / { index index.html; add_header X-debug-message "Location / reached" always; } location ^~ /reset_password/(.*)[a-z]/ { alias /var/www/grades-ui; add_header X-debug-message "Location /reset_password/$1 reached" always; } location ^~ /reset_password { alias /var/www/grades-ui; add_header X-debug-message "Location /reset_password reached" always; } # location /reset_password/([0-9a-z]*) { # root /var/www/grades-ui; # try_files /index.html =404; # } } server { listen 80; if ($host = mygrades.co.uk) { return 301 $host$request_uri; } # managed by Certbot server_name www.mygrades.co.uk mygrades.co.uk; # return 301 https://$host$request_uri; # managed by Certbot proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } 
4
  • Try: location /reset_password { root /var/www/grades-ui; try_files /index.html =404; } Commented Oct 6, 2019 at 19:12
  • It actually worked because it loads correctly, but the url becomes e.g. https://mygrades.co.uk/reset_password/test/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/ Commented Oct 6, 2019 at 19:55
  • Any ideas as to why this could be? Commented Oct 6, 2019 at 19:55
  • To add to this: it turns out my browser was simply caching the previous results and it actually works just fine! @RichardSmith if you were to post this as the answer I will accept it. Commented Oct 7, 2019 at 16:18

2 Answers 2

2

You are confusing your location syntax. The regular expression location is introduced with the ~ or ~* modifiers. The ^~ modifier means something else entirely. See this document for details.

The location ^~ /reset_password { ... } block already matches any URI that begins with /reset_password, including /reset_password/foo. You do not need a regular expression to match the trailing part of the URI.

You could use an alias directive with a regular expression location, but in that case, alias requires the entire pathname to be provided. See this document for details. For example, this should work:

location ~* ^/reset_password { alias /var/www/grades-ui/index.html; } 

But the solution I would suggest is a prefix location with a root and try_files directive. See this document for details. For example:

location ^~ /reset_password { root /var/www/grades-ui; try_files /index.html =404; } 
Sign up to request clarification or add additional context in comments.

Comments

1

The ^~ string is a prefix location modifier which tells nginx to skip processing of regular expression locations if the prefix location is matched. A regular expression location uses just ~ or ~* to ignore case. Check the documentation for more details.

That said, if you don't need to capture any regex pattern matches, just go with a simple prefix location. Regex locations are expensive and they interfere with the natural flow of nginx. The author of nginx, Igor Sysoev, explains in this video.

A good way to use a regex location is to wrap it in a prefix location. This isolates it from the rest of the configuration and makes it easier to debug. Your config will also scale more smoothly. Here's an example:

location /reset_password/ { location ~ /reset_password/([0-9a-z]*) { # ... } } 

2 Comments

Thank you for the detailed explanation. I have actually changed my code to use this method instead!
I'm glad it helped!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.