Author: markt
Date: Thu Jun  2 12:14:20 2016
New Revision: 1746551

URL: http://svn.apache.org/viewvc?rev=1746551&view=rev
Log:
When timeouts occur process them as error events rather than closing the socket 
immediately so that the correct error handling (async listener, read/write 
listener) can be called.

Modified:
    tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1746551&r1=1746550&r2=1746551&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java Thu Jun  2 
12:14:20 2016
@@ -195,6 +195,25 @@ public abstract class AbstractProcessor
             }
         } else if (status == SocketEvent.OPEN_READ && 
request.getReadListener() != null) {
             dispatchNonBlockingRead();
+        } else if (status == SocketEvent.ERROR) {
+            // An I/O error occurred on a non-container thread. This includes:
+            // - read/write timeouts fired by the Poller (NIO & APR)
+            // - completion handler failures in NIO2
+
+            if (request.getAttribute(RequestDispatcher.ERROR_EXCEPTION) == 
null) {
+                // Because the error did not occur on a container thread the
+                // request's error attribute has not been set. If an exception
+                // is available from the socketWrapper, use it to set the
+                // request's error attribute here so it is visible to the error
+                // handling.
+                request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, 
socketWrapper.getError());
+            }
+
+            if (request.getReadListener() != null || 
response.getWriteListener() != null) {
+                // The error occurred during non-blocking I/O. Set the correct
+                // state else the error handling will trigger an ISE.
+                asyncStateMachine.asyncOperation();
+            }
         }
 
         RequestInfo rp = request.getRequestProcessor();

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1746551&r1=1746550&r2=1746551&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Thu Jun  2 
12:14:20 2016
@@ -1462,10 +1462,9 @@ public class AprEndpoint extends Abstrac
                     log.debug(sm.getString("endpoint.debug.socketTimeout",
                             Long.valueOf(socket)));
                 }
-                removeFromPoller(socket);
-                destroySocket(socket);
-                addList.remove(socket);
-                closeList.remove(socket);
+                SocketWrapperBase<Long> socketWrapper = 
connections.get(Long.valueOf(socket));
+                socketWrapper.setError(new SocketTimeoutException());
+                processSocket(socketWrapper, SocketEvent.ERROR, true);
                 socket = timeouts.check(date);
             }
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1746551&r1=1746550&r2=1746551&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Thu Jun  2 
12:14:20 2016
@@ -1041,7 +1041,10 @@ public class NioEndpoint extends Abstrac
                             if (isTimedOut) {
                                 key.interestOps(0);
                                 ka.interestOps(0); //avoid duplicate timeout 
calls
-                                cancelledKey(key);
+                                ka.setError(new SocketTimeoutException());
+                                if (!processSocket(ka, SocketEvent.ERROR, 
true)) {
+                                    cancelledKey(key);
+                                }
                             }
                         }
                     }catch ( CancelledKeyException ckx ) {

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1746551&r1=1746550&r2=1746551&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Jun  2 12:14:20 2016
@@ -103,6 +103,12 @@
         <bug>59564</bug>: Correct offset when reading into HTTP/2 input buffer
         that could cause problems reading request bodies. (violetagg/markt)
       </fix>
+      <fix>
+        Modify the handling of read/write timeouts so that the appropriate 
error
+        handling (<code>ReadListener.onError()</code>,
+        <code>WriteListener.onError()</code> or
+        <code>AsycnListener.onError()</code>) is called. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to