0

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.

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;
}
  • I tried a negative lookahead before but I must've done something wrong, this one works perfectly. Thank you! – Felipe Zavan Dec 17 '18 at 13:27
1

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.

  • I 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 Dec 17 '18 at 1:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.