Search code examples
apachessltomcattomcat8apache2.4

Tomcat assets fail to load over Apache reverse proxy


Accessing my tomcat webapp over SSL (https) has been working for years, but recently something strange started happening, possibly related to using docker container tomcat:8-jdk8 (which is v 8.5.75) instead of tomcat:8.5.41-jdk8 (which is no longer available). When I try to access my tomcat app through Apache's reverse proxy, over SSL (https://example.com/myapp), the main wire framework HTML page loads, but all of the js and css assets get 404s because they are missing the app dir in the base url, so nothing visible actually loads on the page. For example, the html requests https://example.com/assets/ex.js instead of https://example.com/myapp/assets/ex.js (note myapp/).

However, I can access the app and everything is working 100% when accessed without Apache/SSL (http://example.com:8080/myapp).

Most strange of all, if I access the app without SSL (http://example.com:8080/myapp), and then in the same tab, change the url to the SSL path (https://example.com/myapp), then everything loads fine and functions properly. At that point, I can even Empty Cache and Hard Reload, and everything still loads fine over SSL. I checked the headers of all network requests, and everything is loading over SSL. This same behavior occurs in Chrome, Firefox, and Safari. However, in Chrome and Safari, if I visit any other website in that tab and then try to load my app over SSL, it fails; in Firefox, the same tab will keep loading my app regardless of interceding website visits.

The Apache config looks like this:

<VirtualHost *:80>
    Servername example.com

    ##  The following email address is setup in /etc/postfix/localusers
    ServerAdmin webmaster@localhost

    UseCanonicalName On

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://example.com%{REQUEST_URI} [R=301,QSA,L]
    ##  R=redirect, QSA=keep any query string, L=last rule to evaluate, stop.
</VirtualHost>

<VirtualHost *:443>
    Servername example.com
    UseCanonicalName On

    ProxyPass        /myapp http://127.0.0.1:8080/myapp/
    ProxyPassReverse /myapp http://127.0.0.1:8080/myapp/

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key
    SSLCACertificateFile /etc/ssl/certs/ca.crt
    SSLVerifyDepth 2

    # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
    LogLevel warn

    ErrorLog ${APACHE_LOG_DIR}/example_ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/example_ssl-access.log combined
</VirtualHost>

The tomcat config is the default config that comes in the tomcat docker container. I do not have a META-INF/ directory in my project.

Question 1: why does tomcat provide the correct URLs over Apache/SSL only after the browser first visits tomcat directly without Apache/SSL?

Question 2: How can I get this app to load over SSL all the time (by always including the app name in the base url)?


Solution

  • Source and target paths in your redirects are inconsistent. Remove the last / in the target path.

        ProxyPass        /myapp http://127.0.0.1:8080/myapp
        ProxyPassReverse /myapp http://127.0.0.1:8080/myapp
    

    The mapping with moreover / caused a double // in the path, which I guess caused problems down the road with processing the path in generation of the page.