Hi.

This is somewhat of an arcane question and somewhat straddling httpd and tomcat, so if I'm on the wrong list for this, just let me know.

The question is : is there any particular reason why the combination mod_proxy + mod_proxy_ajp (in httpd), does not seem to follow the ProxyPreserveHost directive, when proxying something from httpd to tomcat ?

Re :
- http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypreservehost
quote : "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."
- https://httpd.apache.org/docs/current/mod/mod_proxy_ajp.html
quote : "Note that usually no ProxyPassReverse directive is necessary. The AJP request includes the original host header given to the proxy, and the application server can be expected to generate self-referential headers relative to this host, so no rewriting is necessary."
- http://tomcat.apache.org/tomcat-8.5-doc/config/ajp.html#Proxy_Support

case :
Apache/2.4.25 (Debian)
Apache Tomcat/8.5.14 (Debian)
(on the same host "debx-dev")

(Note: the configuration listed below is fictitious, interpreted/anonymised/summarised for the sake of example. I may thus have committed some typo/error; but I hope it provides a clear enough idea).

# uname -a
Linux debx-dev 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64 
GNU/Linux

On "debx-dev" :
/etc/hosts :
127.0.0.1 localhost myvhost.com mytomcathost.com

httpd config :
...
<VirtualHost *:80>
  Servername myvhost.com
...
ProxyPass /mypath ajp://mytomcathost.com:8009/mypath
ProxyPassReverse / ajp://mytomcathost.com:8009/
ProxyPreserveHost on
...
</VirtualHost>

tomcat server.xml :

...
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
        proxyName="something-different.com"  />
...
    <Engine name="Catalina" defaultHost="localhost">
...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Alias>myvhost.com</Alias>
        <Alias>mytomcathost.com</Alias>
...
        </Host>

Request sent to httpd with URL like : http://myvhost.com/mypath
Received "Host" header in httpd :

Host: myvhost.com

Request proxied to tomcat according to above config.

Received "Host" header in tomcat :

Host: mytomcathost.com

?

- Setting "ProxyPreserveHost off" in httpd does not change the behaviour in any 
obvious way
- removing or modifying the "proxyName" attribute in the Connector does not change the content of the received Host header in any way (*); neither do the <Alias> directives inside the <Host>

According to the documentation referenced above, I would expect that the Host header as received by tomcat would be

Host: myvhost.com

but that does not seem to be the case.

So is this a case of the documentation being wrong, or me misunderstanding it, or a feature in mod_proxy/mod_proxy_ajp, or a bug in mod_proxy/mod_proxy_ajp, or something else ?

(*) this may well be changing the result of request.getServerName() and request.getServerPort() methods in tomcat, and I have not tested that.
But the point here concerns the received "Host" header itself.

(**) I have not really tested this right now, but I believe that when using mod_proxy + mod_proxy_http, to proxy requests to tomcat over HTTP, the ProxyPreserveHost directive *does* change the request Host header content. (It definitely does when the back-end system proxied-to is another Apache httpd instead of tomcat)

-----------------

Note : in a more general sense, I would suggest this additionally :
(I am mentioning this here, just in case such options would be handled by mod_proxy_ajp rather than mod_proxy per se, and could be looked at at the same time as the main issue above).

In httpd, the "ProxyPass" directive admits a series of "options" such as
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] 
[noquery]
These have an effect on /this/ ProxyPass directive only (as opposed to /all/ ProxyPass directives). The "ProxyPreserveHost" on the other hand seems "global" in effect, which seems to not allow doing this selectively, maybe depending on the request URI or the back-end host being proxied to.

It would seem more flexible (and clear) to implement the ProxyPreserveHost selectively, as one of the options of the ProxyPass directive, like e.g.

ProxyPass /mypath ajp://mytomcathost.com:8009/mypath preservehost=[on|off]

(It may even be possible to handle this in such a way as to "override" the global ProxyPreserveHost directive, so as to preserve backward configuration compatibility).

Thank you.



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to