Tricky Rewrite rules

Hi,

I was in need of some advice. I wanted to use a new cache plugin for
Wordpress, that writes static files. But I can’t setup the rules.

The original .htaccess is something like this:

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !.s=.
RewriteCond %{HTTP_COOKIE} !^.comment_author_.$
RewriteCond %{HTTP_COOKIE} !^.wordpressuser.$
RewriteCond %{HTTP_COOKIE} !^.wp-postpass_.$
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond
%{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1index.html.gz
-f
RewriteRule ^(.*)
/wp-content/cache/supercache/%{HTTP_HOST}/$1index.html.gz [L]

RewriteCond %{QUERY_STRING} !.s=.
RewriteCond %{HTTP_COOKIE} !^.comment_author_.$
RewriteCond %{HTTP_COOKIE} !^.wordpressuser.$
RewriteCond %{HTTP_COOKIE} !^.wp-postpass_.$
RewriteCond
%{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1index.html
-f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1index.html
[L]

Somehow I ended with this rules…


location / {
root /var/www/mydomain.com/htdocs;
index index.html index.php;

if ($request_uri ~* ".*s=.*") { rewrite ^(.*)$  /index.php$1  break;

}
if ($http_cookie ~* “^.comment_author_.$” ) { rewrite ^(.)$
/index.php?q=$1 break; }
if ($http_cookie ~
“^.wordpressuser.$” ) { rewrite ^(.)$
/index.php?q=$1 break; }
if ($http_cookie ~
“^.wp-postpass_.$” ) { rewrite ^(.)$
/index.php?q=$1 break; }
if ($http_cookie ~
“^.wordpressuser.$” ) { rewrite ^(.)$
/index.php?q=$1 break; }
if (-f /wp-content/cache/supercache/mydomain.com/$1index.html ) {
rewrite ^(.
)$
/wp-content/cache/supercache/mydomain.com/$1index.html last;
}

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

}


I ommited the Gzip comprobation, mostly because I couldn’t find how to
verify the support on the client.

Between all my iterations of the config I have encountered many weird
stuff, like getting 404’s, 500 and sometimes it returns the php directly
instead of sending to the fcgi service.

Anyway thanks for taking time to get to the bottom of this mail in the
sea of mails in the mailing list and thanks in advance for any advise.

I am also keen to get this working although this is above my ability
unfortunately. Is there a way to pay Igor for this?

By the way I don’t think you’ll need to use the gzip component of
wp-super-cache on nginx since nginx already has on the fly gzip.
(compression as I understand it.)

WP Super Cache provides two forms of cache. To random one off users a
static html file is served.

Here you can see the original php page of your blog that is
dynamically created plus the actual static html file that super cache
creates:

http://yourblog.com/blog/2007/08/20/post-permalink/
http://yourblog.com/wp-content/cache/supercache/yourblog.com/blog/2007/08/20/post-permalink/index.html

To regular users I think a statically cached query of the php is
served up and this still requires php. These users include:

  1. Users who are not logged in.
  2. Users who have not left a comment on your blog.
  3. Or users who have not viewed a password protected post.

When you turn gzip compression on Nginx will turn gzip on or off
depending on the HTTP request version. So you would perhaps disable
gzip compression in wp-super-cache options and then allow nginx to
decide whether or not to compress the static html created by
wp-super-cache.

http://wiki.codemongers.com/NginxHttpGzipModule

I think something like this:

    if ($query_string ~ "..(..)..") {
        set       $var  $1;
        rewrite   ...    ...$var...
    }

HonDev D. wrote:

By the way I don’t think you’ll need to use the gzip component of
wp-super-cache on nginx since nginx already has on the fly gzip.
(compression as I understand it.)

Yeah I forgot to tell that nginx is already serving gzip files, but on
big scenarios, with many users, serving a precompressed file instead of
doing it on the fly, would help greatly on the performance.

also insted of:

if (-f /wp-content/cache/supercache/mydomain.com/$1index.html ) {
  rewrite ^(.*)$ 

/wp-content/cache/supercache/mydomain.com/$1index.html last;
}

I was trying to do something like

if (-f /wp-content/cache/supercache/mydomain.com/$uriindex.html ) {
  rewrite ^(.*)$ 

/wp-content/cache/supercache/mydomain.com/$uriindex.html last;
}

But obviously returns a error, is there a way of a) setting a variable
on nginx b)escape the i on index.html in order to separate the variable
from the text when the config is parsed.

Ok so the apache rewrite rules are basically saying this.

If its not a search (s=.) redirect the wordpress permalink to the static
html file.

If there’s not a cookie with comment_author_ in it redirect the
wordpress permalink to the static html file.

If there’s not a cookie with wordpressuser, wp-postpass_ etc

Wouldn’t something more like this be the way to do it:

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

I had this idea but it didn’t work:

if (!-e /wp-content/cache/supercache/$http_host/$request_filename) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

Ok I also tried this:

if (-e /wp-content/cache/supercache/$http_host/$request_filename) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

Check and see if this directory is here based on the requested file
name. If it’s there use this rewrite rule.

Didn’t work either. Anyone else got any ideas?

Hone wrote:

Ok so the apache rewrite rules are basically saying this.

If its not a search (s=.) redirect the wordpress permalink to the static
html file.

If there’s not a cookie with comment_author_ in it redirect the
wordpress permalink to the static html file.

If there’s not a cookie with wordpressuser, wp-postpass_ etc

Wouldn’t something more like this be the way to do it:

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}
Well that does work, if first the file exists. But before that I have to
check for the existence of the file with a if, but I cant have recursive
if’s. Handling the string’s and queries is not difficult, But Im having
problems after doing the if’s for query’s and cookies.

To be more specific:

if (-f /wp-content/cache/supercache/mydomain.com/$1index.html ) {
  rewrite ^(.*)$

/wp-content/cache/supercache/mydomain.com/$1index.html last;
}

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

Aparently sometimes does work, other gives weird 404’s and 500’s.

Hone wrote:

Maybe another way to do it would be to set up a second backend instance
of nginx on another port which serves all the php dynamic.

  1. http client makes request
  2. if static is required and available the front nginx serves it
  3. if no static is found the request gets proxied to the second nginx
    server with php fastcgi

Your 2nd Nginx would have your normal rewrites and the fastcgi php set
up and your first file could look like this. I haven’t had time to test
this.

upstream 2ndNginx {
server 127.0.0.1:82;
}

server {
listen 80;
server_name supercachestatic.com;
location / {

root /var/www/mydomain.com/htdocs;
index index.html;

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @2ndNginx;

}

location @2ndNginx {
proxy_pass http://2ndNginx;

}

I was thinking that, but apparently, after a couple of tries today, it
seems, the problem resides partially on wp-super-cache, carrying on a
bug from wp-cache with php 5.2.x and fastgi. I will check it later today
in order to see How can be fixed that.

But actually is a good idea. I was thinking on something similar after
reviewing a RoR site this morning. I will check it later as an
alternative. Because my fix for wp-cache/wp-super-cache requires
patching :confused:

Maybe another way to do it would be to set up a second backend instance
of nginx on another port which serves all the php dynamic.

  1. http client makes request
  2. if static is required and available the front nginx serves it
  3. if no static is found the request gets proxied to the second nginx
    server with php fastcgi

Your 2nd Nginx would have your normal rewrites and the fastcgi php set
up and your first file could look like this. I haven’t had time to test
this.

upstream 2ndNginx {
server 127.0.0.1:82;
}

server {
listen 80;
server_name supercachestatic.com;
location / {

root /var/www/mydomain.com/htdocs;
index index.html;

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @2ndNginx;

}

location @2ndNginx {
proxy_pass http://2ndNginx;

}

I have not had problems with wp-cache on php 5.2.x and fastcgi. I
have wp-cache running fine on some other single wordpress installs.

I tried setting up a new mu wordpress install but got a 405 error with
the config. Wordpress entered the upstream name “bugaloo” in the
install set up by default.

upstream bugaloo {
server 127.0.0.1:81;
}

server {
listen 80;
server_name xx.yy.zz.com;
location / {
root /home/monkeyking/public_html;
index index.html;

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @tricky;
}

location @tricky {
proxy_pass http://bugaloo;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server {
listen 81;
server_name xx.yy.zz.com;

access_log logs/monkeyking.access.log;

location / {
root /home/monkeyking/public_html;
index index.php;

rewrite ^./files/(.) /wp-content/blogs.php?file=$1;

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

Ok with this set up it serves static pages but if there is none it
serves the wordpress php 404 error pages for any request. It’s making
it through to the proxy php but category and permalink pages are all
wordpress 404 page. Maybe this idea doesn’t work?

upstream xx.yy.com {
server 127.0.0.1:81;
}

server {
listen 80;

location / {
root /home/monkeyking/public_html;
index index.html;

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @tricky;
}

location @tricky {
proxy_pass http://xx.yy.com;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server {
listen 81;

access_log logs/monkeyking.access.log;

location / {
root /home/monkeyking/public_html;
index index.php;

rewrite ^./files/(.) /wp-content/blogs.php?file=$1;

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

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}

location ~ .php$ {
fastcgi_pass 127.0.0.1:8084;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/monkeyking/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}
}

Ok if I remove the rewrites on server port 81 and put them at location
@tricky I get the index page rendering perfectly but when I click on
to about page /about/ and hello world /hello-world/ it just remains on
the index page.

location @tricky {
if (!-e $request_filename) {
rewrite ^.+?(/wp-.) $1;
rewrite ^.+?(/.
.php)$ $1;
rewrite ^(.*)$ /index.php?q=$1 break;
proxy_pass http://muinstall.com;
}
proxy_pass http://muinstall.com;
}

This seems promising - give it a try.

server {
listen 80;
server_name yourmublogs.com *.yourmublogs.com;

location / {
    root   /home/yourmublogs/public_html;
    index  index.html index.htm index.php;
    rewrite ^.*/files/(.*) /wp-content/blogs.php?file=$1;

    if (!-e $request_filename) {
    rewrite ^.+?(/wp-.*) $1 last;
    rewrite ^.+?(/.*\.php)$ $1 last;

    }

    if ($query_string !~ ".*s=.*") {
     rewrite ^(.*) 

/wp-content/cache/supercache/$http_host/$1index.html;
}

    if ($http_cookie !~ "^.*comment_author_.*$" ) {
     rewrite ^(.*) 

/wp-content/cache/supercache/$http_host/$1index.html;
}

    if ($http_cookie !~ "^.*wordpressuser.*$" ) {
     rewrite ^(.*) 

/wp-content/cache/supercache/$http_host/$1index.html;
}

    if ($http_cookie !~ "^.*wp-postpass_.*$" ) {
     rewrite ^(.*) 

/wp-content/cache/supercache/$http_host/$1index.html
break;
}

    error_page    404  =  @tricky;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    location @tricky {
    rewrite ^ /index.php last;
        fastcgi_pass   127.0.0.1:8095;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME

/home/yourmublogs/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:8095;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME

/home/yourmublogs/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}
}

“WPMU only works without the port number in the URL.”

server {
listen 80;
server_name xx.yy.com;
location / {
root /home/monkeyking/public_html;
index index.html;

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @tricky;
}

location @tricky {
proxy_pass http://xx.yy.com:81;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server {
listen 81;
server_name xx.yy.com;
access_log logs/monkeyking.access.log;

location / {
root /home/monkeyking/public_html;
index index.php;

rewrite ^./files/(.) /wp-content/blogs.php?file=$1;

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

Ok I resend the previous because the email added extra lines:

server {
listen 80;
server_name yourmublogs.com *.yourmublogs.com;

location / {
root /home/yourmublogs/public_html;
index index.html index.htm index.php;
rewrite ^./files/(.) /wp-content/blogs.php?file=$1;

if (!-e $request_filename) {
rewrite ^.+?(/wp-.) $1 last;
rewrite ^.+?(/.
.php)$ $1 last;

}

if ($query_string !~ “.s=.”) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.comment_author_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wordpressuser.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html;
}

if ($http_cookie !~ “^.wp-postpass_.$” ) {
rewrite ^(.*) /wp-content/cache/supercache/$http_host/$1index.html
break;
}

error_page 404 = @tricky;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

location @tricky {
rewrite ^ /index.php last;
fastcgi_pass 127.0.0.1:8084;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/yourmublogs/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}

location ~ .php$ {
fastcgi_pass 127.0.0.1:8084;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/yourmublogs/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}
}

Actually I had to change my static rewrites to this:

rewrite
^/.(/(wp-admin|wp-includes)/..(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
$1 last;
rewrite
^/.(/wp-content/(themes|plugins|mu-plugins)/..(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
$1 last;
rewrite
^./files/(.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
/wp-content/blogs.php?file=$1 last;

Here is an updated config to test:

server {
listen 80;
server_name yourmublogs.com *.yourmublogs.com;

location ~*
^.+.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$
{
root /home/yourmublogs/public_html;
rewrite
^/.(/wp-admin/..(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
$1 last;
rewrite
^/.(/wp-includes/..(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
$1 last;
rewrite
^/.(/wp-content/themes/..(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
$1 last;
rewrite
^./files/(.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$
/wp-content/blogs.php?file=$1 last;
expires 10d;
break;
}

location / {
root /home/yourmublogs/public_html;
index index.html index.htm index.php;

if (!-e $request_filename) {
rewrite ^.+?(/wp-.) $1 last;
rewrite ^.+?(/.
.php)$ $1 last;
}

if ($http_cookie !~* “comment_author_|wordpress|wp-postpass_” ) {
rewrite ^(.*)$ /wp-content/cache/supercache/$http_host/$1index.html;
break;
}

error_page 404 = @tricky;
}

location @tricky {
rewrite ^ /index.php last;
rewrite ^/.(/wp-login.php)$ $1;
rewrite ^/.
(/wp-admin/..php)$ $1;
rewrite ^/.
(/wp-includes/.*.php)$ $1;
fastcgi_pass 127.0.0.1:8084;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
/home/yourmublogs/public_html$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server {
server_name www.yourmublogs.com;
rewrite ^/(.*) http://yourmublogs.com/$1 permanent;
}

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs