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
    ProxyPass / http://localhost:8181/test/
    ProxyPassReverse / http://localhost:8181/test/

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.


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.

  • Since you are already ProxyPass'ing everything to tomcat, what do you need the RewriteRule for? Wouldn't spring security just do what you need it to do? – mahnsc Oct 11 '11 at 18:30
  • It does do what it needs to do up to the moment where it has to perform a redirect. Since it is context-aware, it prepends the context to the redirection url. Combined with the proxy-host, this yields a url of test.example.be/test/foo instead of test.example.be/foo. That's what I need the RewriteRule for, to get rid of the context. – Mopper Oct 12 '11 at 8:11

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

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

The right way to not have the DocumentRoot prepended is to either use RewriteBase directive, or add the PT (PassThrough) flag to your rewrite rule. See here - httpd.apache.org/docs/current/rewrite/flags.html#flag_pt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.