Bug 42727 - CoyoteReader readLine returns null for some post request bodies that are a multiple of MAX_LINE_LENGTH in size
Summary: CoyoteReader readLine returns null for some post request bodies that are a mu...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Connector:Coyote (show other bugs)
Version: 5.5.20
Hardware: All All
: P3 normal with 3 votes (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
: 44060 (view as bug list)
Depends on:
Blocks: 44060
  Show dependency tree
 
Reported: 2007-06-23 06:29 UTC by mike
Modified: 2008-08-14 02:32 UTC (History)
1 user (show)



Attachments
Checks aggregator==null before returning null (695 bytes, patch)
2007-06-27 15:02 UTC, Will Pugh
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description mike 2007-06-23 06:29:58 UTC
i have a webapp running on jboss-4.0.5.GA/apache-tomcat-5.5.20 that reads in 
the http post request body and processes it.

i noticed that for request bodies that didn't contain line separators and that 
had sizes that were exact multiples of 
org.apache.catalina.connector.CoyoteReader.MAX_LINE_LENGTH (4096), i was 
receiving null when calling org.apache.catalina.connector.CoyoteReader.readLine
().

i believe that the problem is at line 155 in 
org.apache.catalina.connector.CoyoteReader, where on the last iteration through 
the loop, "pos" does equal zero and null is returned even though data has been 
aggregated.

here's a command to run in cygwin to easily reproduce the problem:
for requestSize in 4095 4096 4097 8191 8192 8193; do dd if=/dev/zero bs=1c 
count=$requestSize | tr '\000' 'A' | curl --data-binary @- 
http://localhost:8080/DebugJboss/DebugServlet > $requestSize.txt; done;

output from directory listing (size filename):
4095 4095.txt
   0 4096.txt
4097 4097.txt
8191 8191.txt
   0 8192.txt
8193 8193.txt

here's the bulk of the servlet code i used to reproduce the problem:
public class DebugServlet extends HttpServlet {
	protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1)
			throws ServletException, IOException {
		BufferedReader br = arg0.getReader();
		Writer writer = arg1.getWriter();
		String line = null;
		while ((line = br.readLine()) != null) {
			writer.write(line);
		}
		writer.close();
		br.close();
	}
}

it appears that a workaround is to wrap the requests's input stream instead:
BufferedReader br = new BufferedReader(new InputStreamReader(arg0.getInputStream
()));
Comment 1 Will Pugh 2007-06-27 15:02:32 UTC
Created attachment 20405 [details]
Checks aggregator==null before returning null

I attached a patch to check that aggregator==null before returning null.
Comment 2 Mark Thomas 2007-12-11 13:10:25 UTC
*** Bug 44060 has been marked as a duplicate of this bug. ***
Comment 3 Mladen Dryankov 2008-02-20 03:34:28 UTC
I have reproduce similar behavior. 
I cannot read anything from ServletRequest.getInputStream or getReader for
Tomcat ver 5.5.15+.
Any idea?

Regards
Mladen
Comment 4 gui 2008-07-17 08:29:57 UTC
Any chance of getting this fix in tomcat 5.5 ? 

After a few hours of debugging my application, i finally discovered this bug was the root cause. It's still there in Tomcat 5.5.26. 
Comment 5 Mark Thomas 2008-07-17 15:14:32 UTC
Thanks for the patch. It has been applied to trunk and proposed for 6.0.x and 5.5.x.
Comment 6 Mark Thomas 2008-08-14 02:32:38 UTC
This has been fixed in 5.5.x and will be included in 5.5.27 onwards.