I'm attaching an excerpt from the header log of a conversation between nginx and firefox, including two subsequent requests of the same page. Before the first request, no aggregated files exist.

Apparently, the browser requests all files, but only the first aggregated css file is delivered correctly, while all others return "Not Found". The second request is a soft refresh. Here, nginx strangely reports a "Not Modified" on all files, even the ones it was unable to deliver before. As a result, the page comes up unstyled until I clear the browser cache and thus force a full refresh of all files.

However, the files are actually generated correctly and placed in the right folder. The problem just seems to be in their initial delivery.

Hope you're able to make sense of this. Let me know if I can do anything more to investigate.

CommentFileSizeAuthor
agrcache-nginx-ff.txt11.24 KBralf.strobel

Comments

ralf.strobel’s picture

Title: All files except first return 404 (nginx) » Nginx delivers files as 404 in default conf
Component: Code » Documentation
Category: bug » task
Priority: Major » Minor

I've found the problem. It has nothing to do with the module, but is an nginx issue. Turns out the files were being transmitted correctly, but nginx will override the http status to 404 if the original request resulted in a 404, unless you specifically tell it not to.

http://wiki.nginx.org/NginxHttpCoreModule#error_page

All you have to do is insert one character in your server conf to change this:

Old: error_page  404  /index.php;
New: error_page  404 = /index.php;

I'm changing this to a minor documentation issue. It should probably be mentioned so nobody else wastes another few hours figuring this out.

rodrigoaguilera’s picture

I can't get this module to work on nginx 1.2.2 even with that line. Can't you assist me to investigate more?

Here is my conf.

server {
	listen 80;
        server_name mydomain.com;
        root /var/www/drupal7;
 
        access_log /var/log/nginx/mydomain.com.access.log;
        error_log  /var/log/nginx/mydomain.com.log info;
 
        index index.php;
	error_page  404 = /index.php;

        if ($host = 'www.mydomain.com' ) {
		rewrite  ^/(.*)$  http://mydomain.com/$1  permanent;
        }
	location ~ /\. {
  		deny all;
  		access_log off;
  		log_not_found off;
	}
        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }
 
        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }
 
        # This matters if you use drush
        location = /backup {
                deny all;
        }
 
        # Very rarely should these ever be accessed outside of your lan
        location ~* \.(txt|log)$ {
                allow 127.0.0.1;
                deny all;
        }
 
        location ~ \..*/.*\.php$ {
                return 403;
        }
 
        location / {
                # This is cool because no php is touched for static content
                try_files $uri $uri/ @rewrite;
                expires max;
        }
	location ~ ^/sites/.*/private/ {
            access_log  off;
            internal;
        }

        location @rewrite {
                # Some modules enforce no slash (/) at the end of the URL
                # Else this rewrite block wouldn't be needed (GlobalRedirect)
                rewrite ^/(.*)$ /index.php?q=$1;
        }
 
        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
}

Thanks

ralf.strobel’s picture

This isn't a forum. Also, "can't get this module to work" is not very specific of you. Look into what your server actually responds when it's asked to deliver an aggregate file.

Back on topic:
One thing you might try is not to set the error page to just /index.php, but to your drupal @rewrite. That's how I'm doing it. I can't remember if I ever tried to use just the php file. It might not work because drupal doesn't get the request string in this case. My statement above was rather meant to illustrate the difference between having the "=" and not having it.

rodrigoaguilera’s picture

Sorry. I meant that I'm experiencing the same issue with the 404s. the files are transmitted but with the 404 code.
I'm not that experienced with nginx to fully understand what I need to write in the conf file, im just a copypaster.
I will look more into it.

ralf.strobel’s picture

Don't worry, just look more into nginx. Your config up there is very typical for someone coming from Apache, in that it's overcomplicated in more than one place. And your catch-all "\.php$" is a possible security risk. Google it.

Anyway, here is the exact config I'm using. In case anyone still cares about this documentation issue.

  error_page 404 = @drupal;

  location @drupal {
    rewrite ^ /index.php?q=$uri&$args;
  }