Rewritecond for nginx


#1

I think I figured out the answer to my last question about perl CGI. I
put the path to cgi-bin in the fastcgi_params file.

I have another question:

How can I tell nginx to not rewrite certain directories? I use the
RewriteCond in Apache. I googled for the answer and I read that I
should use “if” conditions. But I’m still not totally clear. I’m using
rewrite on most of my php code with:

if (!-e $request_filename) {
  rewrite ^/(.*)$ /index.php?q=$1 last;
}

…and that works fine… now I just want to say: Don’t do any rewrite
for directories named /tmp, /filestore, and /cgi-bin.

I tried the following, thinking that the rewrite rule would accomplish
nothing other than telling nginx not to use any subsequent rewrite
rules. It looks crazy but it’s all I could come up with:

if ($request_filename ~ (tmp|filestore|cgi-bin)) {
rewrite ~/(.*)$ /$1 last;
}

I put those 3 lines before the other 3 lines up above.

What should I have instead?

Thanks,
Chris


#2

On Fri, Feb 27, 2009 at 03:44:51AM -0800, Chris Cortese wrote:

if ($request_filename ~ (tmp|filestore|cgi-bin)) {
rewrite ~/(.*)$ /$1 last;
}

I put those 3 lines before the other 3 lines up above.

What should I have instead?

You should forget to think in inverted RewriteCond/RewriteRule terms
and start to think in human natural locations:

 location / {
     ...
     error_page  404  = /index.php?q=$request_uri;
 }

 location /filestore/ {
     ...
 }

 location /tmp/ {
     ...
 }

 location /cgi-bin/ {
     ...
 }

#3

Thanks Igor. I moved towards the “location” style you described. I got
rid of a lot of extra stuff and I moved all but one vhost (conf.d file)
out of the conf.d directory.

Somehow I broke stylesheets and images.

Also, my cgi stuff is still going to index.php.

This is codeigniter framework, so urls that have /controller/model
should get passed to index.php. So, http://mysite.com/search/metro
should become http://mysite.com/index.php?q=search/metro. This part is
happening. However, I don’t want the rewrite to happen for /images,
/javascript, /style, /tmp, /filestore, etc. Then also I want the
/cgi-bin to be handled by fcgiwrap. Right now if I go to
http://mysite.com/cgi-bin/test.pl, it is still getting sent to
index.php.

This is my config file (domain name here changed to “mysite.com”):

server {
listen 81;
server_name dev.mysite.com;

root /home/my_linux_user/www/dev/mysite/trunk/html/public;
index index.php;

access_log /var/log/nginx/dev_mysite.access.log;
error_log /var/log/nginx/dev_mysite.error.log;

if ($request_filename ~ javascript) {
rewrite ^/javascript/(.*)$ /combine.php?type=javascript&files=$1
last;
}

location /tmp/ {
rewrite ~/(.*)$ /$1 last;
}

location /filestore/ {
rewrite ~/(.*)$ /$1 last;
}

location /cgi-bin/ {
fastcgi_pass unix:/tmp/cgi.sock;
include /etc/nginx/perl_fcgiwrap_params;
}

if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}

location ~* (jpg|jpeg|gif|png|js|css) {
expires 30d;
access_log off;
}

location ~ /index.php {
fastcgi_pass 127.0.0.1:10005;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/my_linux_user/www/dev/mysite/trunk/html/public$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}


#4

On Fri, Feb 27, 2009 at 05:06:28AM -0800, Chris Cortese wrote:

should become http://mysite.com/index.php?q=search/metro. This part is

location /tmp/ {
}
location ~ /index.php {
fastcgi_pass 127.0.0.1:10005;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/my_linux_user/www/dev/mysite/trunk/html/public$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}

You do need these useless rewrite’s and if’s:
rewrite ~/(.*)$ /$1 last;
if (!-e $request_filename) {
if ($request_filename ~ javascript) {

Here is configuration:

server {
listen 81;
server_name dev.mysite.com;

root /home/my_linux_user/www/dev/mysite/trunk/html/public;
index index.php;

access_log /var/log/nginx/dev_mysite.access.log;
error_log /var/log/nginx/dev_mysite.error.log;

location / {
error_page 404 = /index.php?q=$request_uri;
}

location ~* (jpg|jpeg|gif|png|js|css) {
expires 30d;
access_log off;
}

location ~ .php$ {
fastcgi_pass 127.0.0.1:10005;
fastcgi_param SCRIPT_FILENAME
/home/my_linux_user/www/dev/mysite/trunk/html/public$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}

location /javascript/ {
rewrite ^/javascript/(.*)$ /combine.php?type=javascript&files=$1
last;
}

location /tmp/ {
}

location /filestore/ {
}

location /cgi-bin/ {
fastcgi_pass unix:/tmp/cgi.sock;
include /etc/nginx/perl_fcgiwrap_params;
}

}


#5

Thanks again Igor. I’m getting closer. My cgi-bin is no longer getting
routed to index.php (this is a good thing). But, my test cgi
(http://dev.mysite.com:81/cgi-bin/test.pl) is getting a 502 bad
gateway. The error log shows:

2009/02/27 09:17:56 [error] 21381#0: *9 upstream closed prematurely
FastCGI stdout while reading response header from upstream, client:
<my.ip.address>, server: dev.mysite.com, request: “GET /cgi-bin/test.pl
HTTP/1.1”, upstream: “fastcgi://unix:/tmp/cgi.sock:”, host:
dev.escort-space.com:81

in perl_fcgiwrap_params I have:
gzip off; #gzip makes scripts feel slower since they have to
complete before getting gzipped
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

my revised /conf.d/mysite.conf file:

server {
listen 81;
server_name dev.mysite.com;

access_log /var/log/nginx/dev_mysite.access.log;
error_log /var/log/nginx/dev_mysite.error.log;

root /home/my_linux_user/www/dev/mysite/trunk/html/public;
index index.php;

location / {
index index.php;
error_page 404 = /index.php?q=$1;
}

location /style/ {
rewrite ^/style/(.*)$ /combine.php?type=css&files=$1 last;
}

location /javascript/ {
rewrite ^/javascript/(.*)$ /combine.php?type=javascript&files=$1
last;
}

location /tmp/ {
}

location /filestore/ {
}

location /images/ {
}

location /cgi-bin/ {
fastcgi_pass unix:/tmp/cgi.sock;
include /etc/nginx/perl_fcgiwrap_params;
}

location ~* (jpg|jpeg|gif|png|js|css) {
expires 30d;
access_log off;
}

location ~ .php$ {
fastcgi_pass 127.0.0.1:10005;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/my_linux_user/www/dev/mysite/trunk/html/public$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}

location = /style/main_style.php {
fastcgi_pass 127.0.0.1:10005;
fastcgi_param SCRIPT_FILENAME
/home/my_linux_user/www/dev/mysite/trunk/html/public/style/main_style.php;
include /etc/nginx/fastcgi_params;
}
}