You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Jonathan Borden <jb...@mediaone.net> on 2000/03/09 15:20:33 UTC

ServletInputStream bug + fix

Hello and congratulations on some great software :-)

I'm running Tomcat 3.1M1 on NT4.0 using VisualAge 3.0 Java2 to develop.

request.getReader() and request.getInputStream() return an InputStream that
hangs trying to read a POST. The POST was sent from MSIE5.01 via the XMLHTTP
COM object for what it's worth.

The problem appears to be that read(buffer,offs,length) tries to read past
the end of the Http request.

I've extended the ServletInputStream to create a:

ContentLengthInputStream(ServletRequest) that queries the request for its
Content-Length and doesn't try to read past this length.

This appears to solve the problem.

I can post this code, or send it to someone who cares :-)

Jonathan Borden
http://www.grovelogic.com


Re: ServletInputStream bug + fix

Posted by Geoff Soutter <ge...@whitewolf.com.au>.
> request.getReader() and request.getInputStream() return an InputStream
that
> hangs trying to read a POST. The POST was sent from MSIE5.01 via the
XMLHTTP
> COM object for what it's worth.
>
> The problem appears to be that read(buffer,offs,length) tries to read past
> the end of the Http request.

I posted a fix for this pre 3.0, but apparently it was the "wrong time", and
I think it was costin that promised to fix this area for 3.1... basically
the whole code around this area was broken...

haven't looked since then though

geoff


RE: ServletInputStream bug + fix

Posted by Jonathan Borden <jb...@mediaone.net>.
Jason Hunter wrote:
>
>
> Jonathan Borden wrote:
>
> > The problem appears to be that read(buffer,offs,length) tries to
> > read past the end of the Http request.
>
> Others have reported similar problems on other servers with
> MultipartRequest, so I had to revise MultipartRequest to act similar
> to what your ContentLengthInputStream probably does.
>
> > I can post this code, or send it to someone who cares :-)
>
> Go for it.
>
Here it is then:

----ContentLengthInputStream.java-----
package com.grovelogic.servlet;

import java.io.InputStream;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
/**
 * This class fixes a bug in the ServletInputStream returned by
 * HttpServletRequest.getInputStream (and getReader) that causes a hang
 * when reading an HTTP POST, an attempt is made to read past the
 * Content-Length of the body.
 * Also, modify org.apache.cocoon.producer.ProducerFromRequest to read
 *  public Reader getStream(HttpServletRequest request) throws IOException {
 *		return new InputStreamReader(new ContentLengthInputStream(request));
 *	//prior-	return request.getReader();
 *	}
 * Creation date: (3/8/00 8:55:40 PM)
 * @author: Jonathan Borden <jb...@mediaone.net>
 */
public class ContentLengthInputStream extends ServletInputStream {
	int length;
	int index = 0;
	ServletInputStream is;
	public ContentLengthInputStream(ServletRequest request) throws IOException
{
		index = 0;
		length = request.getContentLength();
		is = request.getInputStream();
	}
/**
 * Limit what can be read to no more than Content-Length
 * Creation date: (3/8/00 9:00:46 PM)
 * @return int
 * @exception java.io.IOException
 */
public int read() throws IOException {
		int c = -1;
		if (index < length){
			c = is.read();
			++index;
		};
		return c;
	}
/**
 * Limit what can be read to no more than Content-Length
 * Creation date: (3/8/00 9:00:46 PM)
 * @return int
 * @param buffer byte[]
 * @exception java.io.IOException
 * @exception NullPointerException
 */
public int read(byte[] buffer) throws IOException,NullPointerException {
	return read(buffer,0,buffer.length);
}
/**
 * Limit what can be read to no more than Content-Length
 * Creation date: (3/8/00 9:00:46 PM)
 * @return int
 * @param buffer byte[]
 * @param offset int
 * @param len int
 * @exception java.io.IOException
 * @exception NullPointerException
 * @exception IndexOutOfBoundsException
 */
public int read(byte[] buffer,int offset,int len) throws
IOException,NullPointerException,IndexOutOfBoundsException{
		int lenc = Math.min(len,length-index);
		if (lenc <= 0) return -1;
		int lenr = is.read(buffer,offset,lenc);
		index += lenr;
		return lenr;
	}
}


Re: ServletInputStream bug + fix

Posted by Jason Hunter <jh...@acm.org>.
Jonathan Borden wrote:

> The problem appears to be that read(buffer,offs,length) tries to 
> read past the end of the Http request.

Others have reported similar problems on other servers with
MultipartRequest, so I had to revise MultipartRequest to act similar
to what your ContentLengthInputStream probably does.

This seems like something that should be in the javax.servlet.* classes,
doesn't it, since other servers have the same limitation?  Give the
ServletInputStream the ability to respect a maximum total read length,
so servers can (if they want) construct the class to follow the limit. 
The trick is how to give SIS the length information without changing 
the public API.  No real way to do that.  Maybe in the next API rev we
can have a new constructor?  Wow, we can actually justify having the
class around then!

> I can post this code, or send it to someone who cares :-)

Go for it.

-jh-