Show HN: This weird bug is probably present in your Nginx configuration.
keen.posterous.com
keen.posterous.com
server
{
server_name domainname.com;
root /srv/sites/domainname.com/httpdocs;
index index.php;
access_log /srv/sites/domainname.com/logs/access.log main;
error_log /srv/sites/domainname.com/logs/error.log info;
try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$
{
try_files $uri $uri/ /index.php?$query_string =403;
include /usr/local/nginx/conf/fastcgi_params;
fastcgi_pass phpfpm;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
This will allow static files to be served appropriately, standalone .php files to be run, and anything requiring a frontloader to be passed on accordingly. This should work with most frontloader based frameworks, however certain ones will fail, e.g. symphony (no not symfony)...EDIT: Added change suggested by nbpoole to fix security vulnerability.
Edit: You need to copy the try_files line into the PHP location block. I'd recommend using the following line (I just added =403 to the end of yours, so you return a 403 error rather than a 500 error when try_files fails):
try_files $uri $uri/ /index.php?$query_string =403;Also, I'm assuming that by "move try_files" you really mean "copy a variation of try_files". Sorry for being pedantic, and correct me if I'm wrong.
I should also mention that merely allowing uploads via php.ini is not an issue: you need to be storing them somewhere web accessible. A good rule of thumb for this: if you could put a PHP script in the uploads directory and have it execute, you have a potential problem.
Edit: In our server setup we use a completely seperate server to handle file upload and serving - which does not run on php-fpm so thankfully this does not affect us - however still going to make appropriate changes and a note that this is a possible issue.
if (-f $request_filename) {
expires 30d;
break;
}
Where would it go in this new scenario?location /static_files { try_files $uri @fallback; }
location @fallback { expires 30d; }
Secondly... because NginX configuration is declarative and ifs are imperative (the opposite paradigm). The imperative ifs are actually compiled into a little mini language and evaluated at runtime, but under the hood, ifs are hacky locations. This is the ultimate reason why If is Evil in NginX, and always will be.
In NginX's declarative setup, you declare each separate location and the behavior that should result within that location. In NginX, only one location wins for ultimate processing! Finally, one must consider the order of evaluation of locations. Specifically, it is something like server if, location = (exact match), location ~ (regex match), location, location if --only one location wins, ever... but it may pass through several locations, especially if you add in error_pages and so on and so forth.
So, coming full circle and attempting to answer the question of just why "calling the script, not rendering it, and displaying the actual file"; well, if you have not properly setup your locations such that PHP files always are routed to a PHP processing location, then you will in fact serve PHP files just like any other file.
NginX's configuration language is much like any language - if you don't really know what it is doing, it is quite easy to make it do something you didn't expect.
Have a good flight. I'm stuck in a car for another few hours, myself.
location ~* ^.+.(jpg|jpeg|gif|css|png|js|zip|ico|xml|pdf|html)$ {
access_log off;
expires 30d;
break;
}