We are using Apache 1.3.26 and Tomcat 3.2.2. We've seen some clients to be hanging Apache on SSL read. The cause of this hang seems to be network/TCP/IP issue. The read will eventually times out. When it times out, here's where the problem starts. Tomcat seems to be grabbing some buffer that contains partial data of the previous request and call a servlet with it. The servlet will throw an exception because the data is bad. Here are the details (you will need to pull up the code to see what I mean).
When Apache read times out, mod_jk's jk_ajp13_worker.c::read_into_msg_buff() will return error. mod_jk will drop its connection to Tomcat and retry (up to JK_RETRIES times - see the service() function). In the retry, the HTTP header gets resent to Tomcat. When Tomcat receives this header, it will eventually call Ajp13ConnectorRequest::decodeRequest(). This method will attempt to read more data from mod_jk (the call to con.receive()). This call will fail because mod_jk has yet again drop the connection (in its 2nd retry to call read_into_msg_buff() fails). Since this call (con.receive()) fails, the attribute blen is never set to the content-length of this request. Instead, blen has the value of the content-length of the previous request. Because the call to con.receive() fails, the method decodeRequest() will return -1. The caller to decodeRequest, Ajp13ConnectionHandler::processConnection(), doesn't check the error code and it proceeds to call the servlet. The servlet will issue a read and it will eventually call Ajp13ConnectorRequest::doRead(). In doRead(), I dumped some values of the variables. pos is always 0. blen is some number. The problem happens when blen is less than the length of the buffer (variable len). The method will copy some data from bodyBuff, which is a left-over from previous request. Note, I checked the source code for Tomcat 3.2.4. It doesn't seem to be fixed yet. We may not have the luxury to upgrade to Tomcat 3.3 yet. So I am attempting to fix this, but I have a question: Why does Ajp13ConnectionHandler::processConnection() not check the error code from decodeRequest()? It seems to me like if it gets an error in decodeRequest(), it should not call the service() method which calls the servlet. So the fix I'm proposing is to add these lines (see diff below). I've tested this minimally and seemed to fix the problem I saw. I will need to do more extensive testing, but please let me know what you think. Do you see any problems with doing this? thanks, shinta Index: Ajp13ConnectionHandler.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/service/conne ctor/Attic/Ajp13ConnectionHandler.java,v retrieving revision 1.4.2.1 diff -c -b -w -r1.4.2.1 Ajp13ConnectionHandler.java *** Ajp13ConnectionHandler.java 12 Dec 2000 09:41:43 -0000 1.4.2.1 --- Ajp13ConnectionHandler.java 19 Jul 2002 15:58:47 -0000 *************** *** 157,162 **** --- 157,166 ---- case JK_AJP13_FORWARD_REQUEST: err = req.decodeRequest(msg); + if ( err<0 ) { + moreRequests=false; + break; + } contextM.service(req, res); req.recycle(); -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>