Forum Moderators: phranque

Message Too Old, No Replies

Strange recursion happening with mod rewrite virtual hosts

Apache 2.2.3 server and a mass virtual hosting system

         

dandaman32

5:59 am on Dec 11, 2006 (gmt 0)

10+ Year Member



Hey, I'm having a serious problem getting mod_rewrite to work. Basically what happens is I'm getting a very strange recursion pattern with my mass virtual hosting system. Here's the code in .htaccess:


RewriteCond %{SERVER_NAME} ^([a-z0-9-]*)\.([a-z0-9-]*)\.([a-z0-9-]*)\.([a-z0-9-]*)$
RewriteCond %{REQUEST_URI}!^/_error.php
RewriteCond %{REQUEST_URI}!^/serverlets/
RewriteRule ^(.*)$ %{SERVER_NAME}/$1 [C]
RewriteRule ^([a-z0-9-]+)\.([a-z0-9-]+)\.([a-z0-9-]+)\.([a-z0-9-]+)/(.*)$ serverlets/$4/$3/$2/$1/$5 [L]

(_error.php and /serverlets are two reserved filenames - _error.php is an error handler, and /serverlets is where all the virtual hosts go)

When I request fully.qualified.domain.name/dir1/dir2/, it should silently redirect to /serverlets/name/domain/qualified/fully/dir1/dir2/. But for some reason it redirects silently to /serverlets/name/domain/qualified/fully/dir1/dir2/dir2/dir1/dir2/dir2/.

I found further that requesting /one/two/three/ redirects to /one/two/three/two/three/one/two/three/two/three/, so regex hounds would say that it matches this regex: /^([^/]+)/(.*?)/\2/\1/\2\2$/. I wrote a snippet of PHP code that corrects this problem when multiple-level requests are made for CMS'ed pages. (e.g. requesting /Release_notes/1.0/beta_4 which silently redirects to index.php?title=Release_notes/1.0/beta_4.)

I checked Google, apparently no one else has gotten (or at least reported) this problem. Still trying to figure out if this is a bug or if I suck at regular expressions.

Thanks in advance,
dandaman32

jdMorgan

6:57 am on Dec 11, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That code makes my head hurt --- No, maybe it's just late...

Let's simplify it to avoid the chained rewrite, and see if that helps. This is reminiscent of an old Apache 1.x mod_rewrite bug [archive.apache.org] that kicks in when (.*) patterns are used in intermediate rewrites, which leads to re-injection of partial path info -- just what you're seeing. However, that bug was supposed to be fixed in Apache 2.x.

Regardless, simple is often better, so how about this:


RewriteCond $1 !^(serverlets/¦_error\.php)
RewriteCond %{HTTP_HOST} ^([a-z0-9\-]+)\.([a-z0-9\-]+)\.([a-z0-9\-]+)\.([a-z0-9\-]+)
RewriteRule (.*) /serverlets/%4/%3/%2/%1/$1 [L]

All changes to patterns, variable names, anchoring, etc. are entirely intentional. The RewriteCond order must not be changed; Otherwise, the %1 back-reference to the second RewriteCond pattern will be destroyed.

Change the broken pipe "¦" character in the first RewriteCond pattern to a solid pipe before use; Posting on this forum modifies the pipe character.

Jim

dandaman32

3:26 pm on Dec 11, 2006 (gmt 0)

10+ Year Member



Thanks! That did the trick. It's good to know that I don't suck at regular expressions after all :-)

-dandaman32