In working with some internal groups, we have some classes that perform file uploads
(anyone heard of GroupWise Webaccess?). One of the things they have done in their
servlets that handle this is call the available method on the ServletInputStream so
that they can delay the thread for a small amount of time if there isn't anything
available to be read from the socket. This allows the machine and other threads to do
other processing, and allows the thread that wants to read the data to gracefully
handle a client prematurely shutting down the connection. This functionality works on
other servlet engines (JServ, WebSphere, Novell Servlet Gateway) but doesn't work on
Tomcat because the available() method was never implemented in any of the subclasses.
So when availabe() is called, it just resolves down to java.io.InputStream which is
documented as returning 0 because subclasses should override this method. There are 2
ways to fix this:
1. In BufferedServletInputStream, implement an available() method that returns
limit-bytesRead or 0 whichever is greater. The limit class variable is set to the
value of the Content-Length header and bytesRead is the number of bytes read since
limit was set. (See the attached patch). This is the easy fix but doesn't address
the feature of available that says it will return the number of bytes that can be read
"without blocking". Obviously, if there is a large amount of data, a read will most
likely block at some point depending on how much is asked for.
2. Update BufferedServletInputStream to call reqA.available and then update the
following files to provide this interface:
Request.java
RequestImpl.java
HttpRequestAdapter.java
AJP12RequestAdapter.java
Ajp13RequestAdapter.java
JNIRequestAdapter.java
Each of these classes would need to provide an appropriate available() method.
I'm willing to figure this out and implement #2 if it is deemed the better approach
and only provided #1 because it was a "quick" fix. I'm also willing to figure this
out for the 3.3 tree for either implementation. I would like to get it into the 3.2.2
branch since that is what most of use here are currently using.
Any response (other than flames:-) appreciated.
diff.out