Wednesday, April 6, 2011

mod_rewrite question

I would like to serve /foo and /foo/ locally, but proxy requests for /foo/* to a remote server. However, the following rule matches all of the above. What am I doing wrong?

RewriteRule ^/foo/(.+)$ http://remote.host/$1 [P,L]
From stackoverflow
  • Well, since mod_rewrite normally strips leading slashes from the matched text, I suspect you're either transcribing/anonymizing imperfectly or there's a good deal else going on in your rewrite configuration. That seems further borne out by the impossibility of the pattern /foo/.+ matching /foo.

    Can you expand and double-check what you're posting from your rewrite config, so we can see what else might be going on?

    chaos : What's the proxy error? Right now I'm suspecting that Apache is getting as far as reading the P in your options, trying to initialize its communication with mod_proxy, and dying before it actually does anything with your rule.
    chaos : Okay, guess not then. I assume for the mysterious requests to /foo and /foo/ it says GET /? Well, that makes no sense, but we can probably work around it. Try adding this before your current rule: RewriteRule ^/foo/?$ - [L]
  • I think I got it -- somewhere the default docname is being set to index.php, which is silently being appended to my rewrite.

    RewriteLog output:

    (2) init rewrite engine with requested uri /foo
    (3) applying pattern '^/foo(/.+)+$' to uri '/foo'
    (1) pass through /foo
    (2) init rewrite engine with requested uri /foo/
    (3) applying pattern '^/foo(/.+)+$' to uri '/foo/'
    (1) pass through /foo/
    (2) init rewrite engine with requested uri /foo/index.php
    (3) applying pattern '^/foo(/.+)+$' to uri '/foo/index.php'
    (2) rewrite '/foo/index.php' -> 'http://remote.host//index.php'
    (2) forcing proxy-throughput with http://remote.host//index.php
    (1) go-ahead with proxy request proxy:http://remote.host//index.php [OK]
    
    chaos : Heh. Check for .htaccess files. Five bucks says you're using Wordpress.
  • You will need to escape for the first couple of conditions so that they don't all send them off to the remote host. Try this:

    RewriteEngine On
    RewriteRule ^foo$ /$1 [L]
    RewriteRule ^foo/$ /$1 [L]
    RewriteRule ^foo/([a-zA-Z0-9].*)$ http://example.com/$1 [L]
    

    First rule checks the first condition to be plainly /foo. If so, stay at home.

    Next test checks to see if it's not just /foo/. If so, again, stay local.

    Last test checks to see if you have anything dangling behind a slash, if so, then you probably want the remote host and sends it there.

0 comments:

Post a Comment