0

I have Tomcat running on port 8080, and when I send a request directly to Tomcat it works fine:

curl -IL http://localhost:8080/myapp

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/login.html
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1

I have the following mod_proxy setup in Apache:

ProxyRequests Off
ProxyPreserveHost on
ProxyPass /myapp http://localhost:8080/myapp retry=0
ProxyPassReverse /myapp http://localhost:8080/myapp retry=0

When I make a request that goes through the proxy, I get a 404 from Tomcat. The headers say Apache-Coyote, so I know it's going through the proxy and reaching Tomcat.

curl -LI https://myserver.com/myapp
HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1

I enabled the access log in Tomcat to see what the problem is, and Tomcat's access log is logging any requests that go directly to port 8080, but it isn't logging any requests that go through Apache.

If Apache is mangling the request or something, I would like to see the evidence of that in Tomcat's log. Can anyone tell me how to get Tomcat to log 404's that go through the proxy the same as it logs 404's that don't go through the proxy?

EDIT I also noticed that the 404 only happens when ProxyPreserveHost on is part of the config. If I remove it, the proxy works exactly as expected. But I do need the proxy to pass along the hostname to Tomcat.

EDIT I have now set LogLevel Debug, which shows the full proxy connection in the error log. Unfortunately I'm still not seeing where the 404 came from, but here's the connection:

[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(1506): [client 10.100.10.38] proxy: http: found worker http://localhost:8080/myapp for http://localhost:8080/myapp
[Thu Jan 30 11:42:40 2014] [debug] mod_proxy.c(1020): Running scheme http handler (attempt 0)
[Thu Jan 30 11:42:40 2014] [debug] mod_proxy_ajp.c(677): proxy: AJP: declining URL http://localhost:8080/myapp
[Thu Jan 30 11:42:40 2014] [debug] mod_proxy_http.c(1973): proxy: HTTP: serving URL http://localhost:8080/myapp
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2011): proxy: HTTP: has acquired connection for (localhost)
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2067): proxy: connecting http://localhost:8080/myapp to localhost:8080
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2193): proxy: connected /myapp to localhost:8080
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2444): proxy: HTTP: fam 2 socket created to connect to localhost
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2576): proxy: HTTP: connection complete to 127.0.0.1:8080 (localhost)
[Thu Jan 30 11:42:40 2014] [debug] mod_proxy_http.c(1851): proxy: header only
[Thu Jan 30 11:42:40 2014] [debug] proxy_util.c(2029): proxy: HTTP: has released connection for (localhost)
ricksebak
  • 101
  • 1
  • 6

3 Answers3

0

if its not a copy past error that your "proxy access" is via https then i suggest you check your vhost configuration for SSL.

for all i know you need your mod_proxy setup in both your normal *:80 and *:443 Virtualhost Directive.

so either your Virtualhost Directive does not have the entry or you should show us the *:443 Entry to try to help you more specifically.

Dennis Nolte
  • 2,848
  • 4
  • 26
  • 36
  • Thanks for your reply. My VIRTUALIP:80 virtualhost is just a rewrite rule that redirects to https. The ProxyPass directives that I pasted in my initial are in fact in my VIRTUALIP:443 virtualhost. I have since set LogLevel Debug, and I'll paste the output of that in my initial post. If you still think it would be helpful to post the entire VIRTUALIP:443 virtualhost, I can do that. – ricksebak Jan 30 '14 at 16:47
  • no i dont think so, but what i saw is that you use mod_proxy_ajp and mod_proxy. see this line: mod_proxy_ajp.c(677): proxy: AJP: declining URL http://localhost:8080/myapp you need to change the ProxyPass and ProxyPassReverse to ajp://localhost if you want to use the ajp "addon" to mod_proxy see http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html – Dennis Nolte Jan 30 '14 at 16:58
  • I want the connection to Tomcat to use HTTP, not AJP. – ricksebak Jan 30 '14 at 17:00
  • ok so disable the ajp module, on a normal debian/ubuntu you would do a2dismod mod_proxy_ajp. as for your problem, sorry i dont have any other idea if that does not help which i think . – Dennis Nolte Jan 30 '14 at 17:02
0

This doesn't explain why I get a 404 with ProxyPreserveHost On and then do not get a 404 with ProxyPreserveHost Off, but I found a workaround that lets me leave ProxyPreserveHost off.

Instead of having Apache pass along the hostname to Tomcat, I just put the hostname right in Tomcat's server.xml, as described at http://tomcat.apache.org/tomcat-6.0-doc/proxy-howto.html.

proxyName="www.mycompany.com"
proxyPort="80"/>

This wouldn't be a valid workaround if I had lots of different host names going through the proxy, but I don't. It would still be nice if someone figured out a way to let me turn on ProxyPreserveHost, though.

ricksebak
  • 101
  • 1
  • 6
0

But I do need the proxy to pass along the hostname to Tomcat.

Alternative answer. If the backend is interested in the original Host: header, I would argue that it's better to modify the backend application to handle X-Forwarded-Host: header and make apache httpd to prepare such header (along other X-Forwarded-* headers).

This way you don't require the browser URL and Host: header to always point to the same name. In other words you don't dependend on ProxyPreserveHost on anymore. You can also use multiple hostnames.

kubanczyk
  • 13,502
  • 5
  • 40
  • 55