2

I am setting up a version of our webapp on a new machine running Apache 2.4 and Tomcat 7, and can't get the login to work. The current site is running on Apache 2.2 and Tomcat 6.

Debugging is showing that the request.getParameter() is returning null on the 2.4 site only.

I've checked this in all browsers, and navigating the site works, so AJP is at least partially functional - it's only when I post a form that the form data is not seen my Tomcat.

Config is same on both:

<VirtualHost *:80>
  ServerName      www.example.com
  ServerAlias      example.com
  ServerAlias      cdn.example.com
  ServerAlias      prod.example.com

  ProxyPreserveHost On
  ProxyPass /images/ !
  ProxyPass /font/ !
  ProxyPass /style/ !
  ProxyPass / ajp://localhost:8009/ retry=1 acquire=3000 timeout=600 Keepalive=On
  ProxyPassReverse / ajp://localhost:8009/

And the connector in defined in server.xml as:

<Connector port="8009" address="localhost"
           maxThreads="250" minSpareThreads="5" maxSpareThreads="15"
           connectionTimeout="200000"
           packetSize="16384"
           maxHttpHeaderSize="16384"
           enableLookups="false" redirectPort="8443"
           emptySessionPath="true" URIEncoding="UTF-8" protocol="AJP/1.3"/>

The browser request header is:

Host: prod.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es,sv;q=0.9,de;q=0.8,en;q=0.6,es-MX;q=0.5,en-AU;q=0.4,ja;q=0.3,fr;q=0.1
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 73
Referer: http://prod.example.com/en_US/auth/login.action
Cookie: JSESSIONID=07FB9E1A02A4464C0D65B332B53EF02F
Connection: keep-alive
Upgrade-Insecure-Requests: 1

I enabled direct Tomcat access via port 8080 and login works fine this way too.

The code is coming from the same git repo and branch, so everything else should be identical to the legacy site. Should I be looking into Tomcat 7 or Apache 2.4 changes to track this?

Update: I created a very simple test.jsp with a form set to post. I use...

Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
  String name = (String) paramNames.nextElement();
  String[] values = request.getParameterValues(name);

.. to dump the parameters. Via the direct 8080 URL this works perfectly, but via Apache/AJP all POST parameters are ignored, however if I add manually GET parameters to the URL eg. ?test=123 these work fine.

Update 2: I added output of request.getReader() to my test.jsp and my POST data is showing up correctly there, e.g. t1=Some+text&t2=Testing but request.getParameter("t1") is still null. I must be missing something really stupid.

Update 3: I originally thought this was SSL-related but have now set up a non-SSL VirtualHost and this has exactly the same problem. My test page has a datestamp so it doesn't appear to be a cache issue.

Update 4: I just made the following change which allows form POST data to be processed correctly:

# ProxyPass / ajp://localhost:8009/ retry=1 acquire=3000 timeout=600 Keepalive=On
# ProxyPassReverse / ajp://localhost:8009/
ProxyPass / http://localhost:8080/ retry=1 acquire=3000 timeout=600 Keepalive=On
ProxyPassReverse / http://localhost:8080/

So, does this look like an Apache or Tomcat bug?

Nic Cottrell
  • 9,401
  • 7
  • 53
  • 76

1 Answers1

2

How many items in your POST body? Tomcat has a maximum count of these. Tomcat 7's is very high, 10,000, by default. AJP's doesn't appear to be configurable, although several parameters are. See the following for both:

https://tomcat.apache.org/tomcat-7.0-doc/config/ajp.html

Regarding your question, this article seems to suggest, after exhaustive testing, that it is AJP (although the author's conclusion was that it was tomcat): http://tomcat.10.x6.nabble.com/Tomcat-looses-POST-parameters-td2067515.html . In essence, the data was entering AJP and not appearing in the first filter of Tomcat.

Any reason you don't ProxyPass using HTTP?

mikep
  • 3,841
  • 8
  • 21
  • This applies even to tiny data packets - forms with just a few characters of input text. It looks like it's Tomcat not processing the form data properly when coming via AJP - the bytes are still available via `request.getReader` however. – Nic Cottrell Jun 06 '17 at 18:45
  • And wanted to use ProxyPass with AJP (over HTTP) for performance reasons. – Nic Cottrell Jun 06 '17 at 18:45