lm2a
lm2a

Reputation: 915

Apache2 + Tomcat static resources

I set an Apache2 as a reverse proxy for a Tomcat. My server.xml in Tomcat has the next AJP config:

<!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

And Apache config is:

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ProxyPreserveHost On
        SSLProxyEngine On
SSLEngine On
SSLCertificateFile /home/xxxxxx/store/f******.pem
SSLCertificateKeyFile /home/xxxxxx/p*******.pem
    # Servers to proxy the connection, or
    # List of application servers Usage
    ProxyPass / ajp://localhost:8009/x/
    ProxyPassReverse / ajp://localhost:8009/x/
    ServerName localhost
</VirtualHost> 

My web app is using Spring Security. Currently the Apache is serving pages (jsp) fine, but no static resources. Is impossible to reach any resource. If I put in a browser

https://example.com/x/resources/img/logo.jpg

I can't see the logo. But if I put

https://example.com:8443/x/resources/img/logo.jpg

it appears.

Any help will be very welcomed.

Thanks in advance guys ;-)

Upvotes: 0

Views: 272

Answers (1)

stdunbar
stdunbar

Reputation: 17455

You're not mapping the URL the way you want. You have:

ProxyPass / ajp://localhost:8009/x/

That means that the /x portion is already in the URL and is hidden from outside of Apache. So if you want /x/resources/img/logo.jpg from Tomcat then the URL will be http://hostname.tld/resources/img/logo.jpg outside of Apache.

If you want to maintain the /x in the path then change your mapping to be

ProxyPass / ajp://localhost:8009/

so that the /x will be passed through.

EDIT

In the interest of clarity and to prevent a ton of comments I'll layout the four basic ways to use Apache in front of Tomcat.

1 - Pure pass through. In this case your Apache configuration looks like ProxyPass / ajp://localhost:8009/ (or ProxyPass / http://localhost:8080/ for an HTTP proxy). The Tomcat instance gets the exact same URL that Apache gets. I've used this to let Apache be the SSL endpoint as it's easier and better documented on how to setup SSL on Apache. Usually in this case there is only one Tomcat virtual host.

2 - URL rewrite (sort of). This is what you're looking at now. Apache config looks like ProxyPass / ajp://localhost:8009/appName/. This allows you to "hide" the appName portion of the URL. So if an external user requests http://hostname.tld/blah.jpg the URL that is sent to Tomcat is /appName/blah.jpg The only challenge with this setup is that code on the Tomcat side that generates a link (i.e. an HTML anchor tag) needs to be aware to not generate a URL that includes the /appName in it. In this case there can be multiple Tomcat virtual hosts that may be in parallel to Apache virtual hosts.

3 - Apache serves static resources. In this case your mapping in Apache is something like ProxyPass /dynamic ajp://localhost:8009/appName/. You'd request Tomcat resources at something like http://hostname.tld/dynamic/index.jsp. You'd move your static resources to somewhere Apache can access them and handle that with a prefix on the URL like http://hostname.tld/static/picture.jpg This can be via rewrite rules or other Apache configurations.

4 - Forget Apache. Run Tomcat as a user that can bind to port 80 (root on Unix-like environments) and just serve everything from Tomcat. SSL is a bit of a pain to setup but it can be done and the webapp context (i.e. /x in your case) can be eliminated in a few ways, the simplest being placing your content in ROOT for Tomcat.

Let me know if this makes sense.

Upvotes: 1

Related Questions