1

Can someone shed some light on why this doesn't work the way one would expect it to? In the following nginx configuration, the assumption is that the first nginx will go with the regex-matching image extensions block, and only afterwards would it enter the inner block where the ^~ takes preference over everything else.

It seems nginx is looking at the bigger picture regardless of scope, and matching ^~ /images before the outer regex extension block for a request like /images/something.png?

location ~* \.(css|js|jpg|png|gif|ico)$ {
    expires 7d;
    add_header Image-By-Extension 1;
}

location / {
    location ^~ /images {
        add_header Image-By-Folder 1;
        ...
    }
}
Mahmoud Al-Qudsi
  • 509
  • 1
  • 6
  • 21

1 Answers1

5

Yes nginx has to choose one location so it won't report the matching later even if you are nesting these. When you use ~^ operator you tell nginx to avoid looking at regex location blocks if it's the longest prefixed location block matching the current request URI.

I explained the whole process here : Nginx rewite rules 403 error.

Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50
  • As I said there's no scope, nested location blocks are the same as not nested ones. It's a conveniency when you have if statements and for readability. – Xavier Lucas Oct 12 '14 at 15:47
  • So you cannot use nested location blocks to have nginx actually match two locations (via `break` out of one, perhaps)? – Mahmoud Al-Qudsi Oct 12 '14 at 15:47
  • @MahmoudAl-Qudsi You will never match two location blocks in any case. You just need ordering your rules the right way. – Xavier Lucas Oct 12 '14 at 15:53
  • I didn't want to duplicate the image extension block within every inner location block. *sigh* – Mahmoud Al-Qudsi Oct 12 '14 at 15:54
  • @MahmoudAl-Qudsi If you are starting to duplicate location blocks, you are probably mistaken, take a look at [try_files directive](http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files) and write an unique fallback block. – Xavier Lucas Oct 12 '14 at 15:57
  • I have and am using `try_files` extensively - the thing is that I want to apply a general rule to all images regardless of where they are ultimately served from. e.g. /server1/image.png and /server2/image.png go to different upstream servers via try_files, but both need to also match the image block. – Mahmoud Al-Qudsi Oct 12 '14 at 16:00
  • @MahmoudAl-Qudsi You could do that with a map. – Xavier Lucas Oct 12 '14 at 16:11