This is a duplicate of PR2074, PR5338, PR6804 and possibly others I couldn't find in bugzilla. Basically the problem is, if you have: ProxyPass /foo http://newserver/foo ProxyPassReverse /foo http://newserver/foo Then an SSI of: <!--#include virtual="/foo/bar"--> _will_ be proxied. If instead of ProxyPass you use: RewriteRule /foo(.*) http://newserver/foo$1 [P] then the above SSI is _not proxied_. This is because of: /* * Ignore this rule on subrequests if we are explicitly * asked to do so or this is a proxy-throughput or a * forced redirect rule. */ if (r->main != NULL && (p->flags & RULEFLAG_IGNOREONSUBREQ || p->flags & RULEFLAG_PROXY || p->flags & RULEFLAG_FORCEREDIRECT )) { continue; } in mod_rewrite. If you comment out the RULEFLAG_PROXY, it works as expected. I'm not sure of the consequences this has. Can anyone comment on the reasoning behind this? I believe this also applies to httpd-2.0, but I haven't actually compiled it yet.
This doesn't work perfectly, I've discovered. Take the follwoing setup: ## relevant conf directives DirectoryIndex index.html index.php RewriteRule ^/(.*\.php)$ http://localhost:8888/$1 [P] ## $DocRoot/blah/ contains: index.php and test.html Now...*without* patching mod_rewrite, a request for http://www.domain.org/blah/ will return index.php just fine, and it will be properly proxied over to localhost:8888. And, as this bug points out, if test.html just contains <!--#include virtual="index.php"-->, requests for it return the unparsed source of index.php, which is incorrect. But if you remove the one line from mod_rewrite, allowing proxy requests in subrequests, the situation reverses. The SSI part works properly, but requests for /blah/ give you a directory index instead of the output of index.php. So this patch doesn't do exactly the right thing.
I've done some more digging and think I've come a little closer to the real source of the problem: mod_dir makes subrequests for each of its potential index file names until it finds one to return. Line 165 of mod_dir.c is this: if (rr->status == HTTP_OK && S_ISREG(rr->finfo.st_mode)) { So, for mod_dir to return an index file the subrequest has to be HTTP_OK and it must be a regular file. This works fine with the unpatched mod_rewrite, because it will return HTTP_OK and the file will be there -- even if the server is going to end up proxying it in the end. But, if you patch mod_rewrite then you'll still get the HTTP_OK, but rr->filename will have been changed to start with "proxy:", so S_ISREG() will fail. Which leads to this solution: change the call to ap_sub_req_lookup_uri on line 163 of mod_dir.c to ap_sub_req_lookup_file. ap_sub_req_lookup_file doesn't do the URI translation, so it skips mod_rewrite in the subrequest. But then mod_dir still does an internal redirect, which in turn *does* do the URI translation, so everything works out in the end. With these changes both mod_include and mod_dir do the right thing when they are dealing with a file proxied via mod_rewrite+mod_proxy. I'll attach a patch which changes both parts.
Created attachment 3973 [details] One line fix to each: mod_dir & mod_rewrite
I'm going through the bug db to make sure patches are findable. Please see http://httpd.apache.org/dev/patches.html
Another solution to this problem is to utilize the proxy: moniker instead of [P} to invoke the proxy client. [P] as you have pointed out invokes the proxy client but does not continue with additional includes on the invoked page. Wheras the proxy: moniker is invoked in the file mapping handler which contiues with additional ssi requests. Example: RewriteRule ^(.*) proxy:http://host/$1 This assumes that mod_proxy is installed and configured correctly! The other benefit is that additional SSI requests will continue to be processed on the calling page.
Fixed in 2.1. Thanks for the report and thanks for using Apache.