Reputation: 636
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;
}
Upvotes: 2
Views: 5355
Reputation: 49692
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;
}
Upvotes: 2
Reputation: 10314
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]*) {
# ...
}
}
Upvotes: 1