Keep Alive piles up
Maxim Dounin
mdounin at mdounin.ru
Mon Jun 29 22:21:10 MSD 2009
Hello!
On Mon, Jun 29, 2009 at 01:00:00PM -0400, meto wrote:
>
> server {
> listen 94.23.96.82:80;
> server_name gimpuj.info www.gimpuj.info
> gimpuj.org www.gimpuj.org
> gimpuj.net www.gimpuj.net;
>
> if ($host != www.gimpuj.info)
> {
> rewrite ^(.*)$ http://www.gimpuj.info$1 permanent;
> }
>
> access_log /var/www/vhosts/gimpuj.info/statistics/logs/access_log combined buffer=32k;
>
> location = / {
> rewrite / index.php?action=glowna permanent;
> }
>
> location / {
> index index.html index.php;
> root /var/www/vhosts/gimpuj.info/httpdocs;
> include php_support;
>
> if ( !-e $request_filename ) {
> # rewrites
> rewrite ^/avatar/(.*)\.png /avatar/index.php?user=$1 last;
> ....
> some rewrites
> ....
> rewrite ^/index\.php/(.*) /index.php?$1;
> # end rewrites
> }
I was able to reproduce coredump with the following reduced
config:
location / {
set $true 1;
if ($true) {
# fastcgi_pass here
fastcgi_pass 127.0.0.1:9000;
}
if ($true) {
# no handler here
}
# and no handler here
}
It does happily coredumps on 0.7.59 though. Just for completeness
I've tested 0.7.0 - it coredumps too. No idea why 0.7.59 works
for you.
The problem is that first matching if() installs fastcgi handler
for request, while actual processing takes place in context of
last matching if() (second in the example) and there is no
required fastcgi configs in this context.
Fix is to explicitly use break in if with fastcgi_pass to avoid
further rewrite processing, i.e.:
location / {
set $true 1;
if ($true) {
# fastcgi_pass here
fastcgi_pass 127.0.0.1:9000;
# break to avoid coredump
break;
}
if ($true) {
# no handler here
}
# and no handler here
}
It's not clear for me how to fix code without breaking
more-or-less correct configs using if's, so probably it's a good
idea to wait for Igor's return from vacation.
> }
>
>
> # PLESK statistics below
> location ^~ /plesk-stat/ {
> autoindex on;
> alias /var/www/vhosts/gimpuj.info/statistics/;
> }
> # End of PLESK statistics
>
> include settings;
> }
>
> every domain is built with such config template
>
> php_support
>
> #php support
> if ( $request_filename ~* \.php(.*)$ ) { # is it php?
> fastcgi_pass 127.0.0.1:9000;
> expires off;
> }
>
> fastcgi_index index.php;
> fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
> include fastcgi_params;
>
>
> settings
>
> #limit conns for ddos and slowloris
> limit_conn limit_per_ip 25;
>
> #errors
> error_page 404 /errors_pages/404.html;
>
> location ^~ /errors_pages {
> alias /var/www/errors_pages;
> }
>
>
> #Phpmyadmin
>
> location ^~ /phpmyadmin {
> index index.php;
> root /usr/share;
> include php_support2;
> }
>
> #xcache-admin
>
> location ^~ /xcache-admin {
> index index.php;
> alias /usr/share/xcache/admin;
> #root /usr/share/xcache/admin;
> include php_support2;
> fastcgi_param SCRIPT_FILENAME $request_filename;
> }
> # AW-Stat Icons
> location ^~ /awstats-icon/ {
> alias /usr/share/awstats/icon/;
> }
>
> # deny access to .htaccess files, if Apache's document root
> # concurs with nginx's one
> location ~ /\.ht {
> deny all;
> }
>
>
> php_support2 is same as php_support but passes queries only to local PHP.
>
> Here you have it. As I said nothing special here.
>
> >Using if() on $request_uri/$request_filename suggests that config
> >should be rewritten, but anyway nginx shouldn't coredump.
>
> Why? I know that if is in rewrite module in docs but can't we use it in other places?
Basically, if()'s are evil. Mostly due to the fact that nginx
configuration are declarative while if's are imperative - and this
produces some nasty implementation details as in your problem.
In most situations it's a good idea to avoid if's. And test for
$request_uri/$request_filename means you can do so using
appropriate [regex] locations.
> Do you suggest to use nested location rather than if() in that case? But still (and dont yell) - it worked before.
Yes, separate normal locations or nested ones is the way to go.
Maxim Dounin
More information about the nginx
mailing list