Bug 54947 - Http11NioProtocol generates HTTP 505 responses on valid requests if request is split across multiple packets
Summary: Http11NioProtocol generates HTTP 505 responses on valid requests if request i...
Alias: None
Product: Tomcat 6
Classification: Unclassified
Component: Connectors (show other bugs)
Version: 6.0.36
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: default
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2013-05-09 20:27 UTC by Greg Harris
Modified: 2013-09-11 20:19 UTC (History)
0 users

Patch for trunk (844 bytes, patch)
2013-05-12 21:48 UTC, Konstantin Preißer
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Greg Harris 2013-05-09 20:27:01 UTC
If an HTTP request is broken up across multiple packets *and* the first packet contains a GET request up to "\r" AND the "\n" terminating the first line of the request is included in the next packet Tomcat incorrectly throws an HTTP "505 Version Not Supported" response.  This is with the Http11NioProtocol connector only - the default HTTP/1.1 connector does not exhibit this problem.

An example request:
Packet 1: GET / HTTP/1.1\r
Packet 2: \nHost: localhost\r\n
Packet 3: Connection: Close\r\n\r\n

HTTP/1.1 505 HTTP Version Not Supported
Server: Apache-Coyote/1.1
Date: Thu, 09 May 2013 20:23:58 GMT
Connection: close

The following Python program reproduces the problem for me in both Tomcat 6.0.37 and Tomcat 7.0.39:

import socket
import time

s = socket.socket()
s.sendall("GET / HTTP/1.1\r")
time.sleep(1.5) # make sure the above goes out in its own packet
s.sendall("\nHost: localhost\r\n")
s.sendall("Connection: close\r\n\r\n")
print s.makefile().read()

Moving the "\n" to from the second sendall to the end of the first sendall causes Tomcat to respond correctly.
Comment 1 Konstantin Preißer 2013-05-12 21:48:47 UTC
Created attachment 30272 [details]
Patch for trunk


I can reproduce the issue with current trunk and Tomcat 7.0.40.

Attached is a patch against trunk that fixes the issue for me by resolving a logic error in InternalNioInputBuffer ("end = 0" was set twice: when starting to read the HTTP version up to \r, and after the \n has been received; which meant "end" was set to the position of "\n" instead of "\r", causing the version string to be "HTTP/1.1\r" instead of "HTTP/1.1").
Comment 2 Mark Thomas 2013-05-13 16:13:31 UTC
Restore originally reported version.

By default, bugs get fixed in trunk and back-ported until the reported version is reached so this needs to be left as the original value else 6.0.x might not get fixed.
Comment 3 Konstantin Preißer 2013-05-13 16:58:38 UTC
Ok, sorry for changing the version.
Comment 4 Mark Thomas 2013-05-28 11:34:29 UTC
Thanks for the report, test case and fix.

I added a test to Tomcat's unit tests based on the provided test case that confirmed that problem. I also confirmed the proposed patch fixes the issue.

The patch has been applied to trunk and 7.0.x and will be included in 7.0.41 onwards.

The patch has been proposed for 6.0.x
Comment 5 Mark Thomas 2013-09-11 20:19:42 UTC
Fixed in 6.0.x and will be included in 6.0.38 onwards.

Thanks again for the patch.