1

I made a static mirror of a large PHP-based website, using the following Apache2 rewrite stanzas gets the query string into the filesystem path to serve the static files correctly. Old dynamic url foo/?bar maps to static file foo/index.html@bar, foo/image.php?bar maps to foo/image.php@bar - all with / replaced by %2F wherever it occurs in bar (which is at most 5 times in the original site). To give an example, I have urls like example.com/foo/?bar=baz/quux which I need to map to files like foo/index.html@bar=baz%2Fquux.

# turn off php
php_admin_value engine off

# enable rewrites
RewriteEngine on

# rewrite .../?... to .../index.html@... with s|/|%2F|g

RewriteCond %{QUERY_STRING} ^([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2\%2F%3 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2\%2F%3\%2F%4 [L,T=text/html]

# rewrite .../image.php?... to .../image.php@... with s|/|%2F|g

RewriteCond %{QUERY_STRING} ^([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3\%2F%4 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3\%2F%4\%2F%5 [L,T=image/jpeg]

The Apache2 config above works fine, but we are migrating to nginx, which I'm having trouble configuring for this use case. I can think of a couple of workarounds, the first is using a huge map directive listing all the urls on the site (undesirable due to size), the second is writing a small custom cgi script (undesireable as this is intended to be a static mirror).

Is there an elegant solution?

(Renaming all the files on the filesystem is an option, if it would make things easier, though I don't see how, but changing the browser-facing URLs isn't possible.)

0

Isn't something like this going to work for the first 4 ? You have to put them in the reverse order so that the more global location don't match the rest before it can reach it targets.

location ~ ^/(?<path>.+)/(?<path2>.+)/(?<path3>.+)/(?<path4>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string%2F$path%2F$path2%2F$path3%2F$path4 break;
}

location ~ ^/(?<path>.+)/(?<path2>.+)/(?<path3>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path\%2F$path2\%2F$path3 break;
}

location ~ ^/(?<path>.+)/(?<path2>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path\%2F$path2 break;
}

location ~ ^/(?<path>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path break;
}

I tried with a directory called foo, in which I've put files called

  • index.html@bar%2Ffoo

  • index.html@bar%2Ffoo%2Ffoo2

when I access http://myserver/foo/?bar I get the file index.html@bar%2Ffoo, when I access http://myserver/foo/?bar I get the file index.html@bar%2Ffoo%2Ffoo2.

I let you adapt for image.php

| improve this answer | |
  • This is not what I need, which is to regex replace slashes in the query string, not the location. I have urls like example.com/foo/?bar=baz/quux which I need to map to files like foo/index.html@bar=baz%2Fquux – Claude Apr 20 '16 at 14:40
  • alright I understood it wrong then, sorry. I'll delete the answer – Pierre-Alain TORET Apr 20 '16 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.