Nginx location match multiple extensions unless path starts with specific word
Solution 1
You can use location ^~
definition, for example:
location ^~ /rails/ {
# your directives for "/rails/..." URIs here
}
location ~* \.(jpg|jpeg|gif|css|png|js|ico|json|xml|txt|html)$ {
gzip_static on;
gzip on;
expires max;
add_header Cache-Control public;
}
According to documentation:
If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.
Update
Another way to do this without declaring extra location
block is to use negative regex assertion:
location ~ ^(?!/rails/).*\.(jpg|jpeg|gif|css|png|js|ico|json|xml|txt|html)$ {
gzip_static on;
gzip on;
expires max;
add_header Cache-Control public;
}
Solution 2
Write location "/rails" block above of defined block for safety.
Quotes from the nginx location description
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.
Related videos on Youtube
Felipe Zavan
Updated on September 18, 2022Comments
-
Felipe Zavan over 1 year
How can I write a location block that matches any path ending in the following extensions:
jpg|jpeg|gif|css|png|js|ico|json|xml|txt|html
Unless the path starts with "/rails" (eg: /rails/randomstring/image.png)?
I currently have this basic block:
location ~* \.(jpg|jpeg|gif|css|png|js|ico|json|xml|txt|html)$ { gzip_static on; gzip on; expires max; add_header Cache-Control public; }
But this would match "/rails/randomstring/image.png" and I don't want that.
-
Felipe Zavan over 5 yearsI already have a “location /“ block above that sends the request to rails/puma, this way i’d need to declare it again with the same contents but with “location /rails” instead, no? I don’t send just “/rails” paths to rails.
-
Felipe Zavan over 5 yearsI tried a negative lookahead before but I must've done something wrong, this one works perfectly. Thank you!