Strange results when chaining try_files
Maxim Dounin
mdounin at mdounin.ru
Sun Nov 8 14:40:35 MSK 2009
Hello!
On Sun, Nov 08, 2009 at 09:11:28PM +1100, Jeff Waugh wrote:
> Hi all,
>
> Wondering if anyone can explain what's going on here... I'm trying to come
> up with a "more perfect" WordPress + WP-Super-Cache configuration, using
> try_files to fall back through static files, cached files and finally, the
> dynamic script... the challenge is the preconditions on the use of the on
> disk cached files (checking cookies and so on).
>
> Here's a summary of the virtual host's configuration:
>
> server {
> listen 80;
> server_name trunk.press.home;
> root /srv/wordpress/trunk;
> index index.php;
>
> access_log /var/log/nginx/access.log;
> error_log /var/log/nginx/error.log notice;
> rewrite_log on;
>
> location / {
> try_files $uri @supercache;
> # ultimately this would have more in it, but I have
> # stripped it down to clarify the test case
> }
>
> location @supercache {
> set $idx 'index.html';
> set $supercache '/wp-content/cache/supercache/$host$request_uri$idx';
> # ^ nasty, but it's because I can't do $request_uriindex.html :-)
Just a side note: ${request_uri}index.html should do the trick.
>
> if ( $http_cookie ~* wordpress ) {
> set $supercache '';
> break;
> }
>
> try_files $supercache /index.php;
> }
>
> location ~ \.php$ {
> # totally normal, working fastcgi configuration
> }
> }
>
> A no-cookie request to http://trunk.press.home/ and /about/ works fine. A
> request to / with the cookie works fine. However, a request to /about/ with
> the cookie returns a 404.
>
> Here's what the logs show:
>
> [notice] 28051#0: *21690 "wordpress" matches "wordpress=true", client:
> 192.168.10.121, server: trunk.press.home, request: "GET /about/ HTTP/1.1",
> host: "trunk.press.home"
>
> [error] 28051#0: *21690 "/srv/wordpress/trunk/about/index.php" is not
> found (2: No such file or directory), client: 192.168.10.121, server:
> trunk.press.home, request: "GET /about/ HTTP/1.1", host:
> "trunk.press.home"
>
> It's that second error which surprises me -- why, with the cookie, is the
> ultimate request going to /trunk/about/index.php, not /trunk/index.php? AND,
> if I change the index to index.html, it'll fail looking for THAT (ie. this
> is not a result of the try_files in @supercache).
>
> This fails even if I set $supercache to a nonsense file rather than a blank
> string.
>
> Thoughts?
Well, it sounds somewhat funny. You tried to rewrite config to
use try_files instead of if's and fall into one of if tarpits. :)
In this particular case try_files isn't inherited into implicit
location created by if, and therefore doesn't work. Reduced
test-case as have it in my collection "why if is evil" is:
# try_files wont work due to if
location /if-try-files {
try_files /file @fallback;
set $true 1;
if ($true) {
# nothing
}
}
There are two possible solutions: either move if() to server{}
level, or go to another explicit location in if() (via "rewrite ...
last" or "return ...").
Something like this should work:
location @supercache {
error_page 404 = /index.php;
if ($http_cookie ~* wordpress) {
return 404;
}
try_files /path/to/check /index.php;
}
[just a usual disclaimer]
If is evil. If you use if() in your config - prepare for fun.
The are only 2 things that can be safely done within an if() in
location:
1. rewrite ... last;
2. return ...;
[end of disclaimer]
Maxim Dounin
More information about the nginx
mailing list