Fixed comet processing.
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 16 Jun 2006 20:55:06 +0000 (20:55 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 16 Jun 2006 20:55:06 +0000 (20:55 +0000)
The following bug was existing:
When a comet request had begun, and the browser sent some more data, the Tomcat APR component was never reading the data from the socket and lead to two kinds of failures
1. The CometServlet.read returned false, cause no data was read, and the socket closed
2. If the CometServlet.read was overwritten and return true, the thread got stuck in a loop, forever hanging.

The solution was to read the incoming data from the socket, update the content length of the request, and make sure that the input filters would still allow to read the data.

I think the following features still need to be fixed:
1. If CometServlet.read return false, the adapter should call CometServlet.end, not CometServlet.error
2. If CometServlet.read throws an error, then the adapter should call CometServlet.error
3. When CometServlet.read returns false, don't close the socket, keep alive should still work and we should still be able to process more HTTP requests on that connection

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@414906 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/coyote/http11/Http11AprProcessor.java
java/org/apache/coyote/http11/InternalAprInputBuffer.java

index 841e81f..6c31811 100644 (file)
@@ -743,9 +743,19 @@ public class Http11AprProcessor implements ActionHook {
         \r
         try {\r
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);\r
-            error = !adapter.event(request, response, error);\r
-            if (request.getAttribute("org.apache.tomcat.comet") == null) {\r
-                comet = false;\r
+            int data = inputBuffer.readSocketData();\r
+            if ( data > 0 ) {\r
+                int contentLength = request.getContentLength();\r
+                if (contentLength>=0) request.setContentLength(contentLength + data);\r
+                for (int i=0; i<inputBuffer.activeFilters.length; i++) {\r
+                    //this resets the remaining flag and the content length on the filter\r
+                    //if we don't do this, then request.getInputStream.read will return 0\r
+                    if (inputBuffer.activeFilters[i]!=null) inputBuffer.activeFilters[i].setRequest(request);\r
+                }\r
+                error = !adapter.event(request, response, error);\r
+                if (request.getAttribute("org.apache.tomcat.comet") == null) {\r
+                    comet = false;\r
+                }\r
             }\r
         } catch (InterruptedIOException e) {\r
             error = true;\r
index 699e2f8..fffde33 100644 (file)
@@ -350,6 +350,17 @@ public class InternalAprInputBuffer implements InputBuffer {
         }\r
 \r
     }\r
+    \r
+    public int readSocketData() {\r
+        bbuf.clear();\r
+        int nRead = Socket.recvbbt(socket, 0, buf.length - lastValid, readTimeout);\r
+        if (nRead > 0) {\r
+            bbuf.limit(nRead);\r
+            bbuf.get(buf, pos, nRead);\r
+            lastValid = pos + nRead;\r
+        }\r
+        return nRead>=0?nRead:-1;\r
+    }\r
 \r
 \r
     /**\r