Tomcat behind Apache httpd – ignoring RewriteRule

httpdjavaspringframeworktomcat

I have a fairly common setup of a tomcat app server behind apache httpd using mod_proxy. My virtualhost looks like this:

<VirtualHost test.example.be:80>
    ServerName test.example.be
    RewriteEngine on
    RewriteRule ^/test/(.*)$ /$1
    ProxyRequests Off
    ProxyPreserveHost On

    <Proxy *>
            Order deny,allow
            Allow from all
    </Proxy>
    ProxyPass / http://localhost:8181/test/
    ProxyPassReverse / http://localhost:8181/test/
</VirtualHost>

The application deployed in tomcat, 'test', uses a framework (spring security) that is context-aware and thus prepends the context root when it redirects. So, when it redirects to a page called foo.html which is located in the root, it redirects to
bleh://test.example.com/test/foo.html.
This url does not exist and gives a 404. Since I cannot control the prepending of the context root, I thought I could get around this using mod_rewrite, by removing the context root. Unfortunately, this does not work: it's as if the RewriteRule gets completely ignored.

I did notice one strange thing: a request for
bleh://test.example.com/test/foo.html
will not even get forwarded to tomcat: I get the familiar 404 page from apache httpd. If I enter any other bogus url, like
bleh://test.example.com/jfaklkfdjljfkl,
I get the 404 page from tomcat. I would expect
bleh://test.example.com/test/foo.html
to yield a call to
bleh://localhost:8181/test/test/foo.html,
but obviously I'm missing something here.

I'm far from an expert in these matters so any help would be greatly appreciated.

UPDATE

I've made some progress on the issue. I was told that it is possible to log the debug output from mod_rewrite, so I did exactly that. Below is the relevant piece of those logs:

[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) init rewrite engine with requested uri /test/notify
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (3) applying pattern '^/test/(.*)$' to uri '/test/notify'
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) rewrite '/test/notify' -> '/notify'
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) local path result: /notify
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) prefixed with document_root to /usr/local/apache/htdocs/notify
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (1) go-ahead with /usr/local/apache/htdocs/notify [OK]

So what's happening here is that mod_rewrite is doing exactly what it should do, but for some reason, apache doesn't pass the url through to mod_proxy, instead it prepends /usr/local/apache/htdocs and attempts to resolve that. So the new question is: how do I get apache to not prepend /usr/local/apache/htdocs and just pass the url through to tomcat?

PS: I had to replace 'http' with 'bleh' on several places because apparantly the number of links you can post is limited.

Best Answer

Just use [P] flag to pass the request to the mod_proxy:

RewriteRule ^/test/(.*)$ http://localhost:8181/$1 [P]
Related Topic