views:

150

answers:

3

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]
A: 

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
Here's a verbatim copy/paste, I'm testing with dummy values. /foo, /foo/, and /foo/blah all return proxy errors rather than local 404s. <VirtualHost *:80> DocumentRoot /srv/proxytest RewriteEngine On RewriteRule ^/foo/(.+)$ http://remote.host/$1 [P,L] </VirtualHost>
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
Proxy ErrorThe proxy server received an invalid response from an upstream server.The proxy server could not handle the request GET /foo/blah.Reason: DNS lookup failure for: remote.host
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]
chaos
A: 

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]
Heh. Check for .htaccess files. Five bucks says you're using Wordpress.
chaos
+1  A: 

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.

random