Bug 49718 - Fix for bug 46984 breaks HTTP 0.9 requests
Summary: Fix for bug 46984 breaks HTTP 0.9 requests
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Connector:HTTP (show other bugs)
Version: 5.5.29
Hardware: Sun Solaris
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-06 14:58 UTC by Nick Langlois
Modified: 2010-08-25 12:37 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Langlois 2010-08-06 14:58:59 UTC
Summary:
   * issue found in 5.5.29 and still exists in 5.5.30.
   * support for HTTP simple requests is broken as of tomcat 5.5.28.
   * root cause: fix added to incorrect block in request line parser.

Details:

We've recently upgraded our product to use Apache Tomcat 5.5.29 from Apache Tomcat 5.5.25.  While testing, it was determined that some of our older clients who sent the following HTTP 0.9 request, described as "Simple Requests" in RFC 1945:

GET /login/servlet/myservlet?ReplyType=ACTION&User=blah&Password=blahblah


Would receive the following response:

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Date: Thu, 29 Jul 2010 19:26:06 GMT
Connection: close

For the same request using Tomcat 5.5.25, we'd get the correct "Simple-Response" as required by RFC 1945.

After turning debugging on, I determined that tomcat was throwing the following exception:

2010-07-29 15:49:22,068 [http-8080-Processor24] DEBUG org.apache.coyote.http11.Http11Processor - Error parsing HTTP request header
java.lang.IllegalArgumentException: Invalid character (CR or LF) found in method name
 at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:474)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
 at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
 at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
 at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
 at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
 at java.lang.Thread.run(Thread.java:595) 


Which doesn't make any sense.

After some testing, I found that if an extra space character was added after the URI, I would once again get the correct "Simple-Response" back from tomcat.


Based on the error message, I assumed it was likely the following bug fix in tomcat 5.5.28 that likely introduced the issue:

46984: Reject requests with invalid HTTP methods with a 400 rather than a 501.

Looking through the source, I found that this is the code block that is throwing the exception:

$ diff ./apache-tomcat-5.5.27-src/connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java ./apache-tomcat-5.5.28-src/connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java
471a472,476
>             // Spec says no CR or LF in method name
>             if (buf[pos] == Constants.CR || buf[pos] == Constants.LF) {
>                 throw new IllegalArgumentException(
>                         sm.getString("iib.invalidmethod"));
>             }
763c768
<                 throw new IOException
---
>                 throw new IllegalArgumentException
$ 


And digging through the code repository, this is the subversion revision in which this issue was introduced:

svn diff -c 781763 http://svn.apache.org/repos/asf/tomcat/


Although I've only briefly perused this code, it seems that the likely error is that this code block was added to the "Reading the URI" code block as opposed to the "Reading the method name" code block, as intended.
Comment 1 Nick Langlois 2010-08-11 17:38:42 UTC
Tested same scenario with:

 ./version.sh
Using CATALINA_BASE:   /localdisk/data/apps/apache-tomcat-6.0.29
Using CATALINA_HOME:   /localdisk/data/apps/apache-tomcat-6.0.29
Using CATALINA_TMPDIR: /localdisk/data/apps/apache-tomcat-6.0.29/temp
Using JRE_HOME:        /localdisk/data/apps/jdk1.6.0_21
Using CLASSPATH:       /localdisk/data/apps/apache-tomcat-6.0.29/bin/bootstrap.jar
Server version: Apache Tomcat/6.0.29
Server built:   July 19 2010 1458
Server number:  6.0.0.29
OS Name:        Linux
OS Version:     2.6.9-34.ELsmp
Architecture:   i386
JVM Version:    1.6.0_21-b06
JVM Vendor:     Sun Microsystems Inc.
$


And with:

$
$ ./version.sh
Using CATALINA_BASE:   /localdisk/data/apps/apache-tomcat-6.0.29
Using CATALINA_HOME:   /localdisk/data/apps/apache-tomcat-6.0.29
Using CATALINA_TMPDIR: /localdisk/data/apps/apache-tomcat-6.0.29/temp
Using JRE_HOME:        /localdisk/data/apps/jdk1.5.0_17
Using CLASSPATH:       /localdisk/data/apps/apache-tomcat-6.0.29/bin/bootstrap.jar
Server version: Apache Tomcat/6.0.29
Server built:   July 19 2010 1458
Server number:  6.0.0.29
OS Name:        Linux
OS Version:     2.6.9-34.ELsmp
Architecture:   i386
JVM Version:    1.5.0_17-b04
JVM Vendor:     Sun Microsystems Inc.
$


In both cases, the issue is NOT reproducible.  Thus, tomcat 6.0.x stream seems unaffected.
Comment 2 Mark Thomas 2010-08-25 12:37:43 UTC
Thanks for the report and the thorough analysis. This has been fixed in 5.5.x and will be included in 5.5.31 onwards.