NGINX Location Directive Issue

All I want to do is this.

I am trying to add this header:

add_header Cache-Control ‘no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0’;

To all files in a directory and all of it’s subdirectories.

So let’s call the directory /nocache/, I figured this would get the job done:

location  /nocache/ {
  # kill cache
  add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

I figured this would add the header to anything called,

so these should all have the header:

/nocache/
/nocache/runvideo.php
/nocache/util/ajax.php

The only one that shows the header is the index of /nocache/, while the other two URLs don’t show the header coming through, so nginx think they not apply.

What is the correct location directive for this?

Cheers!
Ryan

Could you post your full configuration please? It’s probably two location blocks conflicting with each other.

Hello!

Actually, I think this solved the issue:


location ~  /nocache/ {
        index index.php;
                location ~ \.php$ {
                        fastcgi_pass 127.0.0.1:9000;
                        fastcgi_index index.php;
                        fastcgi_param SCRIPT_FILENAME /home/ramrod/public_html/$fastcgi_script_name;
                        include fastcgi_params;
                }
                 # kill cache
                add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
                if_modified_since off;
                expires off;
                etag off;

        }

So it looks like having location ~ /nocache/ ensures files in the folder area also included, while location /nocache/ did not work the same way. Is that how it’s supposed to go?

I have no other location calls with the same directory. What other conflicts could exist?

Cheers!

Not really, no. location /nocache/ is a prefix and should work if there are no other location blocks.
However, given the behaviour you’ve described there most likely a location ~ \.php block somewhere that is selected to serve the .php files from /nocache/ as regex matches trump prefix matches in nginx.

When that happens the location /nocache/ is ignored, as nginx will only ever select one location at a time - it won’t mix and match location blocks.

By changing location /nocache/ to location ~ /nocache/ this location is now also a regex match, and thus can now win over the php regex location.

Also, there has to a location for php files somewhere, otherwise nginx wouldn’t execute the php, it would just return the source file.

For more information on how Nginx matches requests to a location block, see https://www.keycdn.com/support/nginx-location-directive

I actually do have this one line in the config file as well. It’s not a location directive, just a rewrite to ensure a trailing slash takes place:

rewrite ^/((?!(nocache|utilities|md)).+)/$ /$1 permanent;

Could that be causing the issue?

Actually, after the location directive discussed, on the bottom of all the directives I do have :

 location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /home/ramrod/public_html$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_param X-Real-IP $http_x_real_ip;
        }

You think this is why the location directive of /nocache/ doesn’t work like it should in regards to forcing no-cache headers on php?

Also, please forgive me for tacking on an additional question, but I think it is related.

I have a password protected folder:

location /protected/ {
        auth_basic "Required Login";

        auth_basic_user_file /home/ramrod/.htpasswd;
        index index.php;
}

This works, if you go to mydomain.com/protected/

But if you were to go to mydomain.com/protected/index.php

You can easily get around the folder protection, and the page will load.

Is that because of the php rules declared later in the configuration?

Cheers!
Ryan

Yes, because for PHP files only the location ~ \.php$ block will be used, and the location /nocache/ will be ignored, as Nginx prefers regex matches over prefix matches.

What you could do is change location /nocache/ to location ^~ /nocache/, then it’s still a prefix match, but Nginx will prefer it over regex matches.

No, same as above it is because the location ~ \.php$ is a regex match, and location /protected/ is a prefix match, and Nginx prefers regex matches over prefix.

Solution is the same above, change location /protected/ to location ^~ /protected/.

You should really read (not scan) the article I linked to earlier, that explains all this pretty clearly :slight_smile:

1 Like

Thanks so much for your help!

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.