21

Is there any way I connect Apache to Tomcat using an HTTP proxy such that Tomcat gets the correct incoming host name rather than localhost? I'm using this directive in apache:

ProxyPass /path http://localhost:8080/path

But it comes through as localhost, which is useless when we have a bunch of sites on the same server. I could set the host manually in the server config:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           proxyName="pretend.host" proxyPort="80" />

But that again doesn't serve more than one site. And I don't like the idea of using a different internal port for each site, that sounds really ugly.

Is there no way to transfer the port when I proxy it?

(If you ask why I don't just use AJP, the answer is this error. I'm trying everything I can before giving up on Tomcat and Apache entirely)

Community
  • 1
  • 1
Marcus Downing
  • 10,054
  • 10
  • 63
  • 85

3 Answers3

40

The settings you are looking for are:

<VirtualHost *:80>
  ServerName public.server.name

  ProxyRequests Off
  ProxyPreserveHost On

  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  ProxyPass / http://localhost:8080/
  ProxyPassReverse / http://localhost:8080/
</VirtualHost>

Note that we're using localhost as the proxy target. We can do this since we enable ProxyPreserveHost. The documentation states that

It is mostly useful in special configurations like proxied mass name-based virtual hosting, where the original Host header needs to be evaluated by the backend server.

which sounds exactly like what you are doing.

Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
  • How would you cater for static files? I.e. how would you tell Apache to server everything requested from `/static` how would you set the document root for this? – Luke Nov 13 '13 at 10:51
  • @Luke - ProxyPassMatch should help you : http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassmatch – Robert Munteanu Nov 22 '13 at 12:23
5

I think your best bet if you want multiple sites on the same server is to use virtual hosts in your Apache configuration. Here's an example:

<VirtualHost *:80>
ServerName server.domain.com

ProxyRequests Off
<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

ProxyPass / http://server.domain.com:8080/
ProxyPassReverse / http://server.domain.com:8080/
<Location />
    Order allow,deny
    Allow from all
</Location>

As long as you have server.domain.com registered in your external DNS, the incoming host name will be displayed in client URLs. I'm running a single server hosting 6 separate sites, including 3 that are back by Tomcat, using this method.

gareth_bowles
  • 20,760
  • 5
  • 52
  • 82
  • We are of course using virtual hosts in Apache, but I was using localhost in the ProxyPass directive. Using the appropriate domain instead is acceptable, but not quite perfect - it overrides the domain on which the request came in, information which is then used down the line. – Marcus Downing Jun 07 '09 at 15:07
0

You can still use AJP, and you should since it's faster than HTTP. Just make sure to enable it in http.conf:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

In that case, this configuration works for me:

<VirtualHost *:80>
  ServerName public.server.name

  ProxyRequests Off
  ProxyPreserveHost On

  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  ProxyPass / ajp://localhost:8080/
# ProxyPassReverse might not be needed,
# it's only for redirecting from inside.
#  ProxyPassReverse / ajp://localhost:8080/
</VirtualHost>
John Mikic
  • 640
  • 6
  • 11