Opened 13 years ago
Last modified 18 months ago
#86 accepted defect
the "if" directive have problems in location context
Reported by: | s "hr" berder | Owned by: | somebody |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | |
Keywords: | Cc: | ||
uname -a: | Linux bjs-fl-dev-web06 2.6.18-274.12.1.el5xen #1 SMP Tue Nov 29 14:18:21 EST 2011 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/0.8.55
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-51) TLS SNI support disabled configure arguments: --user=nginx --group=nginx --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-file-aio --with-mail_ssl_module --with-ipv6 --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' |
Description
To start, I'm doing tricky stuff so please don't point out at the weird things and stay focused on the issue at hand.
I'm mixing a configuration with userdir and symfony2 (http://wiki.nginx.org/Symfony) for a development environment, php is using php-fpm and a unix socket.
The userdir configuration is classic, all your files in ~user/public_html/
will be accessible through http://server/~user/
.
I add to this the fact that if you create a folder ~user/public_html/symfony/
and put a symfony project in it (~user/public_html/symfony/project/
) it will have the usual symfony configuration applied (rewrites and fastcgi path split).
Here you go for the configuration :
# match 1:username, 2:project name, 3:the rest location ~ ^/~(.+?)/symfony/(.+?)/(.+)$ { alias /home/$1/public_html/symfony/$2/web/$3; if (-f $request_filename) { break; } # if no app.php or app_dev.php, redirect to app.php (prod) rewrite ^/~(.+?)/symfony(/.+?)/(.+)$ /~$1/symfony/$2/app.php/$3 last; } # match 1:username, 2:project name, 3:env (prod/dev), 4:trailing ('/' or # end) location ~ ^/~(.+?)/symfony(/.+)/(app|app_dev)\.php(/|$) { root /home/$1/public_html/symfony$2/web; # fake $request_filename set $req_filename /home/$1/public_html/symfony$2/web/$3.php; include fastcgi_params; fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $req_filename; fastcgi_pass unix:/tmp/php-fpm.sock; }
The second block (PHP backend) works on its own. The first block (files direct access) works on its own.
You can see that I already had a problem with PHP but went around it with creating my own variable.
To help understand, here is a sample of a symfony project layout (I removed some folders to help the comprehension):
project/ src/ [... my php code ...] web/ app_dev.php app.php favicon.ico
If I try to access http://server/~user/symfony/project/favicon.ico
I see this in the logs :
2012/01/17 16:36:25 [error] 27736#0: *1 open() "/home/user/public_html/symfony/project/web/favicon.icoavicon.ico" failed (2: No such file or directory), client: 10.11.60.36, server: server, request: "HEAD /~user/symfony/project/favicon.ico HTTP/1.1", host: "server"
If I remove the block that tests $request_filename
, it works but I have to remove the rewrite as well.
The server is a CentOS 5.7 and the nginx is coming from the EPEL repository.
Unfortunately my C skills are down the floor so I can't really provide a better understanding of the problem. I tried to poke around the code but with not much luck.
Change History (9)
comment:1 by , 13 years ago
Status: | new → accepted |
---|---|
Summary: | alias and $request_filename don't play along → the "if" directive have problems in location context |
Version: | 0.8.x |
comment:2 by , 11 years ago
sensitive: | → 0 |
---|
A particular case with regex location + alias + if is resolved by c985d90a8d1f.
Leaving the ticket open as there are other cases which still need to be fixed, see http://wiki.nginx.org/IfIsEvil.
comment:4 by , 8 years ago
See also #633, which is basically identical to the same problem with if
:
# try_files wont work due to if location /if-try-files { try_files /file @fallback; set $true 1; if ($true) { # nothing } }
In both cases try_files
is not inherited into an implicit location created with if
/ limit_except
and this results in unexpected behaviour.
This is one of the known problems with the "if" directive used in a location context, see http://wiki.nginx.org/IfIsEvil. Reduced test case is as follows (copied from the wiki page in question):
Workaround is not to use if, or use it in a safe way, see the wiki page in question.