Mixing Apache's mod_rewrite with mod_proxy

View: New views
3 Messages — Rating Filter:   Alert me  

Mixing Apache's mod_rewrite with mod_proxy

by mraible :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I want to configure Apache to front a Tomcat installation. I've done this in the past with mod_jk. I've got that setup and working. I also configured mod_proxy and got that working thanks to Graham King's excellent instructions[1]. I don't know which one is a better solution, but I have them both working, so I'm flexible.

Now onto my problem.  I'd like to use mod_write to rewrite some URLs for doing A/B Testing. In other words, we'll deploy entirely new WAR files when we have a test, then use the magic of Apache's mod_rewrite, mod_jk and possible the UrlRewriteFilter to keep the URLs somewhat consistent between version A and version B. Here's some questions I have for those folks who might've done this before:

   1. Is it possible to use Apache's mod_rewrite to map http://www.domain.com/?v=1 to http://www.domain.com/1 (this allows us to have two different applications/wars served up to the same domain).
   2. If #1 is possible, I'm assuming it's possible to add a RewriteRule for allowing the parameter to be anywhere in the query string?

I believe this is all possible. However, I am having difficulty getting mod_jk to allow mod_rewrite to be processed first. If I have the following in httpd.conf, it seems like htdocs/.htaccess gets bypassed.

JkMount /* loadbalancer

Likewise, if I use mod_proxy (config below) with RewriteRules in <Location />, the request is dispatched to Tomcat w/o processing the rules.

<Proxy balancer://tomcats>
   BalancerMember ajp://localhost:8009 route=tomcat1
   BalancerMember ajp://localhost:8010 route=tomcat2
</Proxy>

<Location />
    ProxyPass balancer://tomcats/ stickysession=JSESSIONID
</Location>
 
I've written this up in a blog post[2] as well, but figured this list is probably the best place to get this question answered.

Thanks!

Matt

[1] http://www.darkcoding.net/software/goodbye-mod_jk-hello-mod_proxy/
[2] http://raibledesigns.com/rd/entry/mixing_apache_http_server_mod

Re: Mixing Apache's mod_rewrite with mod_proxy

by press :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Matt, See configuration below.  I hope this helps you - Clay

Test Cases for Requirement #1
http://www.domain.com/?v=1                                        -> http://www.domain.com/1
http://www.domain.com/?v=2                                        -> http://www.domain.com/2

Test Cases for Requirement #2
http://www.domain.com/?q=foo&v=1                     -> http://www.domain.com/1
http://www.domain.com/?v=1&q=foo                     -> http://www.domain.com/1
http://www.domain.com/?p=bar&v=1&q=foo         -> http://www.domain.com/1

#mod_proxy_ajp, mod_proxy_balancer and mod_rewrite configuration

#webapp1 or webapp2 are deployed
RewriteCond    %{QUERY_STRING}          (.*)v=(1|2)      
RewriteRule     ^(.*)$                                 /%2/? [L,R]

#default to webapp1  for anything else
RewriteCond    %{QUERY_STRING}           (.*)v=([^12])    
RewriteRule     ^(.*)$                                 /1/?   [L,R]


<Proxy balancer://cluster >
    BalancerMember ajp://localhost:8009 route=tomcat1
    #BalancerMember ajp://localhost:8010 route=tomcat2
</Proxy>

<Location /1 >
    ProxyPass balancer://cluster/servlets-examples
</Location>

<Location /2 >
    ProxyPass balancer://cluster/jsp-examples
</Location>


Re: Mixing Apache's mod_rewrite with mod_proxy

by mraible :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I got this working with mod_jk and the following configuration for mod_rewrite:

RewriteEngine On

# http://domain/?v=1 --> http://domain/app1/?v=1
RewriteCond     %{QUERY_STRING}     v=([^&]+)
RewriteRule     ^(.*)$              /app%1/$1 [L]

# http://domain --> http://domain/app (default ROOT in Tomcat)
RewriteRule     ^$                  /app/ [L]

My mod_jk configuration is:

JkMount /app* loadbalancer

I tried to use mod_proxy and mod_proxy_ajp, but for some reason (with Apache 2.2.4 on OS X), I couldn't get the following to work (from httpd.conf):

<Proxy balancer://cluster>
    BalancerMember ajp://localhost:8009 route=tomcat1
    BalancerMember ajp://localhost:8010 route=tomcat2
</Proxy>

<Location ~ /app(.*)>
    Order Allow,Deny
    Allow from all
    ProxyPass balancer://cluster stickysession=JSESSIONID
    ProxyPassReverse /
</Location>

I tried LocationMatch as well, but no dice. Something about my configuration doesn't seem to allow Location|LocationMatch to read the regular expressions properly.

The nice thing about using mod_proxy is I could use mod_proxy_html to rewrite all the outgoing links so they're the same as the incoming links (notice my mod_rewrite configuration does not do redirects).

The problem I'm trying to solve now is how to round-robin between apps 1, 2 and 3.  If there's a "v" parameter or "v" cookie, I want to disable round-robin-ing.  But otherwise, I want to assign an app so all the A/B tests are used equally by anonymous users.

Matt
press wrote:
Hi Matt, See configuration below.  I hope this helps you - Clay

Test Cases for Requirement #1
http://www.domain.com/?v=1                                        -> http://www.domain.com/1
http://www.domain.com/?v=2                                        -> http://www.domain.com/2

Test Cases for Requirement #2
http://www.domain.com/?q=foo&v=1                     -> http://www.domain.com/1
http://www.domain.com/?v=1&q=foo                     -> http://www.domain.com/1
http://www.domain.com/?p=bar&v=1&q=foo         -> http://www.domain.com/1

#mod_proxy_ajp, mod_proxy_balancer and mod_rewrite configuration

#webapp1 or webapp2 are deployed
RewriteCond    %{QUERY_STRING}          (.*)v=(1|2)      
RewriteRule     ^(.*)$                                 /%2/? [L,R]

#default to webapp1  for anything else
RewriteCond    %{QUERY_STRING}           (.*)v=([^12])    
RewriteRule     ^(.*)$                                 /1/?   [L,R]


<Proxy balancer://cluster >
    BalancerMember ajp://localhost:8009 route=tomcat1
    #BalancerMember ajp://localhost:8010 route=tomcat2
</Proxy>

<Location /1 >
    ProxyPass balancer://cluster/servlets-examples
</Location>

<Location /2 >
    ProxyPass balancer://cluster/jsp-examples
</Location>