The Mystery of ProxyPassReverse

The mod_proxy_ajp module for Apache has many advantages over mod_jk for connecting a Tomcat server to an Apache front. For me, the crucial advantage was the ProxyPassReverseCookiePath directive, which allows me to map the session cookies of a Tomcat web application (other than the root application) into the root of a virtual host.

Unfortunately, many tutorials contain misleading advice, and recommend this pattern for the ProxyPassReverse, which will break if the web application issues a redirect:

ProxyPass /jspdir ajp://localhost:8009/jspdir
ProxyPassReverse /jspdir ajp://localhost:8009/jspdir

The purpose of ProxyPassReverse is to rewrite the headers of HTTP redirect responses by a simple string substitution. Unfortunately, when the webapplication sends a redirect, it will send a redirect to a http: URL, not an ajp: URL. This will not match the argument of ProxyPassReverse, so the header will be passed through unchanged.

The working form looks like this, in a more complete example:

<VirtualHost *:80>
    ServerName www.example.com
    ...
    ProxyRequests Off
   <Proxy *>
     Order deny,allow
     Allow from all
   </Proxy>
    ProxyPass / ajp://localhost:8009/jspdir/
    ProxyPassReverse / http://www.example.com/jspdir/
    ProxyPassReverseCookiePath /jspdir /
    ...
</VirtualHost>

Searching for mod_proxy_ajp produces 5 bad examples and only one good on the first page. I’ve found the broken form in pages from training companies, the Zimbra Wiki, and professionally published books.

How do so many people get away with this? AJAX applications such as Zimbra have no need to redirect, and simple JSP examples don’t redirect. In these cases the ProxyPassReverse line is simply cargo-cult configuration, copied from example to example and doing nothing at all.

6 replies
  1. Adrian Cox
    Adrian Cox says:

    The ProxyPassReverse is still required to rewrite the headers in the redirect, whether you use AJP or HTTP. To get a clearer view of what is going on, install Firebug and look at the network activity during the redirect.

    You should see that without the ProxyPassReverse line, an application redirect to “test.jsp” will become a HTTP redirect to “http://www.example.com/jspdir/test.jsp”. The ProxyPassReverse line will translate that redirect to the correct “http://www.example.com/test.jsp”.

  2. MIke
    MIke says:

    Thank you, thank you, thank you. Everybody else neglected this very important part of the configuration. I actually needed both, but now it works like a charm.

Trackbacks & Pingbacks

Comments are closed.