0

I'm trying to put an Apache server in front of a Tomcat server. Apache's documentation states regarding the ProxyPreserveHost option: When enabled, this option will pass the Host: line from the incoming request to the proxied host, instead of the hostname specified in the ProxyPass line.

I built a simple scenario. I setup a virtual host in Apache and set ServerName and ServerAlias. I also set ProxyPreserveHost Off. The forwarding of the request is initiated by ProxyPass / ajp://tomcat001:8009/ Tomcat's server.xml has a line host name="tomcat001". When I now call tomcat001 - what happens to be set as ServerName - in the browser everything works nicely. When I call tomcat001a - the host that is set as ServerAlias - Tomcat informs be the called file does not exist under /ROOT - meaning it calls Tomcat's default site.

I now wonder what the Apache documentation means by hostname specified in the ProxyPass line? Don't they mean the target site? I expect the tomcat host provided there to be called, under what hostname it might have ever reached Apache.

Addition: 20161023

httpd-vhosts.conf

<VirtualHost *:80>
  DocumentRoot "D:/Webs/tomcat001"
  ServerName tomcat001
  ServerAlias tomcat001a

  LogLevel debug rewrite:trace3 

  <Directory "D:/Webs/tomcat001">
      AllowOverride All
      Require all granted
      DirectoryIndex index.cfm
      OPTIONS +indexes
  </Directory>

  ProxyRequests Off

  ProxyPreserveHost Off
  ProxyPass / ajp://tomcat001:8009/
  ProxyPassReverse / http://tomcat001:8009/
</VirtualHost>

server.xml

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log" suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b" />

  </Host>
  <Host name="tomcat001" appBase="webapps" autoDeploy="true" unpackWARs="true">
    <Context path="" docBase="D:/Webs/tomcat001">
      <JarScanner scanClassPath="false"/>
    </Context>
  </Host>

1 Answer 1

0

When an HTTP client requests a URL, the client sets the HTTP Host header to be everything between the scheme and the URI path. So for example:

http://www.example.com:1234/path/to/index.html?arg1=value1&arg2=value2
  • scheme = http
  • host name = www.example.com
  • port = 1234
  • URI path = /path/to/index.html
  • query string = arg1=value1&arg2=value2

The Host header in this case would be www.example.com:1234.

When using HTTP proxying, by default, the host header that Apache sets (Apache is the client in a reverse proxy situation) will be the relevant part of the URL in the ProxyPass line. So if you had:

ProxyPass / http://mytomcatapp:8009/

The requests to your backend would contain a host header with the string mytomcatapp:8009. However for AJP proxying this is not the default. As per the documentation, https://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html#usage, with AJP, the Host header is preserved by default and so in your case it will be whatever the users browser set it to be.

It might be a tomcat context problem, but you'll need to show more of your configuration to be sure. In general the URI you proxy an application to should be the same URI path that the application is deployed under. It is not that this is required, just that is avoids a lot of possible problems. So:

# Good
ProxyPass / http://backend.example.com:8080/
ProxyPass /app1/ http://backend.example.com:8080/app1/
# Not so good
ProxyPass / http://backend.example.com:8080/app1/
ProxyPass /app1/ http://backend.example.com:8080/

You should also be careful to match trailing slashes on the arguments to ProxyPass and ProxyPassReverse directives. i.e. present on both, or not present on both.

In summary, please show more of your configuration.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .