Removing Tomcat context from virtual host URLs (mod_jk, mod_rewrite)

I have one instance of Tomcat containing several webapps, each of which is accessible through it / Context. Tomcat is behind httpd (actually Debian Apache2) configured with virtual hosts to serve each application / context. Communication of Tomcat with mod_jk.

This works fine when I don't need to remove the context from the URLs: when the root of the virtual domain is requested, the requested is redirected to domain.com/Context.

However, for one application, I do need to remove the context. I believe this can be done using mod_rewrite and passing the rewritten url to mod_jk to go to the correct Tomcat context. So my available Debian Apache2 file looks like this:

NameVirtualHost * <VirtualHost *> ServerName domain.be DocumentRoot /home/webapp/app/static/domain/ RewriteEngine on RewriteRule ^/(.*)$ /Context/$1 [L,PT] RewriteLog "/var/log/apache2/domain-rewrite.log" RewriteLogLevel 4 JkLogFile /var/log/apache2/domain-mod_jk.log JkLogLevel debug JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " JkMount /Context w1 JKMount /Context* w1 JkOptions +ForwardURICompat ErrorLog /var/log/apache2/domain_error.log CustomLog /var/log/apache2/domain_access.log combined LogLevel warn </VirtualHost> 

According to the docs, the [PT] and + ForwardURICompat flags should result in a rewritten URL passed to jk_mod. However, this does not seem to be happening.

The URL is being rewritten, but it looks like mod_jk is ignoring it: the request for domain.be/Context, for example, is being rewritten as / Context / Context, but mod_jk as / Context is still passed.

Any ideas? By the way, I cannot use mod_proxy at the moment.

thanks

+6
tomcat apache mod-rewrite mod-jk virtual-hosts
source share
5 answers

@Josh, I think this solution will not work if tomcat does any redirects. This is a typical example, for example, in an application requiring login. When the user is not authenticated, the application will be redirected to something like / login, but tomcat will add the current context, for example, to / context / login, so that at the end the context is displayed in the URL.

As you mentioned in your other question / answer, using only mod-jk plus tomcat virtual hosts, this is an option, but there you will need to deploy your applications like ROOT.war, which may not be so simple. There is a workaround, so your application can simply be inserted into the tomapat webapps folder, but, as I described here, the server will deploy the application at least twice.

It would be great if RewriteRule [P] plus JkOptions + ForwardURICompat could work, but it is not. BTW I tested this, and I know that mod_proxy really works, since I proxied my site to cnn.com, and I got my page under my site URL. The following are the BTW logs for requests that use a proxy server:

 127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/ 127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK] 127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/login 127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/login [OK] 127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/j_spring_security_check 127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/j_spring_security_check [OK] 127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/ 127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK] 
+4
source share

I will leave my original answer, but this is wrong. The correct way to do this would be with Tomcat VirtualHost:

http://tomcat.apache.org/tomcat-6.0-doc/virtual-hosting-howto.html

The official passage through the link above is exactly what I used several times. I will not try to weld it here.

The concept is the same as Apache Vhost. Create a virtual host (for example, for something.yourtdomain.com ) and deploy the web application for the ROOT application ( / ) for this vhost, and everything is installed. Thus, if you already have a ROOT webapp, you may have another in another domain, and the previous one will not be affected.

As Nestor mentioned, the Apache rewrite rule will not handle things like libs tags and frameworks that automatically create merge / form / etc actions for you based on the context root. In this case, they will create the correct context root ( / ).

+2
source share

I have used this with great success:

 RewriteEngine On RewriteCond %{REQUEST_URI} !^/(Context/.*)$ RewriteRule ^/(.*)$ /Context/$1 [P,L] 

Notes on your situation:

  • You will need to get mod_proxy to work, or [P] will be ignored and the request will be redirected instead of the proxy. This is not true.
  • +ForwardURICompat is part of mod_jk and takes effect after overwriting.
  • mod_jk ignores the request because it never gets there. You need a RewriteCond (see above) to prevent requests / context rewriting.

I'm currently looking for a way to do this without mod_rewrite and instead just mod_jk and Tomcat <Host> . But I have problems with apache, mod_jk and Tomcat hosts that play well together. The above should work just fine for you.

+1
source share

Following the prompts given by Nestor Urquiza, I was able to solve the problem by specifying an additional Host in tomcat server.xml, because, as said, tomcat responds to the j_security_check request with the forward command to the browser, which inevitably contains the context name so that users trying to log in into the system, get 408 errors. Therefore, the real end-to-end operation inside the Apache VirtualHost directive JkMount /* worker1 achievable by creating the intended context of a ROOT .

Apache httpd.conf [and / or included .conf] file:

 <!-- the subdomain --> <VirtualHost *:80> ServerName appWelcome.example.org ServerAlias www.appWelcome.example.org JKMount /* worker1 </VirtualHost> <!-- with mod_jk set up --> LoadModule jk_module modules/mod_jk.so JWorkersFile /etc/apache2/workers.properties JkShmFile /var/log/apache2/mod_jk.shm 

Thus, in order to match the entire request made in the http://appWelcome.example.org/ subdomain directly in the tomcat in-charge / appWelcome context, the appWelcome context must be addressable with the request to http://appWelcome.example.org:8080/

So, the tomcat server.xml file will carry a separate Host for the application you want to expose :.

 <Server ...> <Service> <Engine defaultHost="localhost" ...> <Host name="appWelcome.example.org" appBase="appWelcomeBase" ... > <Valve ... /> </Host> <Host name="localhost" appBase="webapps" ...> <!-- this Host is typically shipped with manager, host-manager, docs, sample, examples and a default ROOT context that shows tomcat default home. --> <Valve ... /> </Host> </Engine> </Service> </Server> 

Note that permissions (and the selinux if enabled context) must be adjusted to simulate the default values โ€‹โ€‹of Host as follows:

$CATALINA_HOME/conf/Catalina/app.example.org as $CATALINA_HOME/conf/Catalina/localhost

$CATALINA_HOME/appWelcomeBase as $CATALINA_HOME/webapps

In this case, all that remains to be done is to rename the problem and move the web archive appWelcome.war for automatic deployment in the created appBase (replacing $ CATALINA_HOME with its value, for example / var / www / tomcat 7):

 # mv $CATALINA_HOME/webapps/appWelcome.war $CATALINA_HOME/appWelcomeBase/ROOT.war 

Voila!

0
source share

Use mod_proxy_ajp instead of mod_jk, as shown below:

 <VirtualHost *:80> ServerName domain.be DocumentRoot /home/webapp/app/static/domain/ ... ProxyPass /Context ajp://localhost:8009/Context ProxyPass / ajp://localhost:8009/Context/ ... </VirtualHost> 
-one
source share

All Articles