Nested location doesn't work properly

When nginx chooses a location to process a request, it may choose the inner or outer location block. It does not combine the statements from both.

The rewrite is not inherited by the nested location. If you want the rewrite to apply to all locations, you should place it in server block scope.

The regular expression of your rewrite statement is sufficiently specific, that it can be moved as is.

For example:

rewrite "^/static[0-9]{10}/(.*)$" /static/$1 last;

location /static {
    location ~* \.pdf$ {
        add_header Access-Control-Allow-Origin *;
        add_header Content-Disposition 'inline';
    }
    ...
}

Of course, it may be more efficient to just repeat the rewrite statement in both location blocks.


An alternative approach is to avoid the rewrite altogether and use a regular expression location to remove the anti-cache token by using an alias directive. See this document for more.

For example:

location ~ "^(?<prefix>/static)[0-9]{10}(?<suffix>/.*)$" {
    alias /path/to/root$prefix$suffix;

    location ~* \.pdf$ {
        add_header Access-Control-Allow-Origin *;
        add_header Content-Disposition 'inline';
    }
    ...
}

Note that regular expression location block have a different evaluation order to prefix location blocks. See this document for details.


While the best answer for this question is what I checked as the best I want to post the solution I used to solve my problem. It's not necessary to define a nested location block to add a header to some of requests. Instead I used an if to check a regex condition and do what I want.
Look at the following block I wrote to handle this:

location /static {
    if ( $request_uri ~* \.pdf$ ) {
        add_header Access-Control-Allow-Origin *;
        add_header Content-Disposition 'inline';
    }

    #Remove Anti cache token
    rewrite "^/static[0-9]{10}/(.*)$" /static/$1 last;
    ...
}