Handle infinite timeouts for both soTimeout and keepAliveTimeout
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 6 Sep 2011 22:56:40 +0000 (22:56 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 6 Sep 2011 22:56:40 +0000 (22:56 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1165918 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/coyote/http11/Http11NioProcessor.java
java/org/apache/coyote/http11/Http11Processor.java
java/org/apache/tomcat/util/net/AbstractEndpoint.java
java/org/apache/tomcat/util/net/AprEndpoint.java
java/org/apache/tomcat/util/net/NioEndpoint.java

index 6ad66d4..d105fa5 100644 (file)
@@ -137,7 +137,7 @@ public class Http11NioProcessor extends AbstractHttp11Processor<NioChannel> {
                         if (comettimeout != null) attach.setTimeout(comettimeout.longValue());
                     } else {
                         //reset the timeout
-                        if (keepAlive && keepAliveTimeout>0) {
+                        if (keepAlive) {
                             attach.setTimeout(keepAliveTimeout);
                         } else {
                             attach.setTimeout(soTimeout);
@@ -177,7 +177,7 @@ public class Http11NioProcessor extends AbstractHttp11Processor<NioChannel> {
             long soTimeout = endpoint.getSoTimeout();
 
             //reset the timeout
-            if (keepAlive && keepAliveTimeout>0) {
+            if (keepAlive) {
                 attach.setTimeout(keepAliveTimeout);
             } else {
                 attach.setTimeout(soTimeout);
@@ -421,9 +421,11 @@ public class Http11NioProcessor extends AbstractHttp11Processor<NioChannel> {
         openSocket = true;
         // Check to see if we have read any of the request line yet
         if (inputBuffer.getParsingRequestLinePhase() < 2) {
-            // Haven't read the request line. Must be keep-alive
-            // Make sure poller uses keepAlive from here onwards
-            socket.setTimeout(endpoint.getKeepAliveTimeout());
+            if (socket.getLastAccess() > -1 || keptAlive) {
+                // Haven't read the request line and have previously processed a
+                // request. Must be keep-alive. Make sure poller uses keepAlive.
+                socket.setTimeout(endpoint.getKeepAliveTimeout());
+            }
         } else {
             // Started to read request line. Need to keep processor
             // associated with socket
index 6b4178c..51db71d 100644 (file)
@@ -345,15 +345,6 @@ public class Http11Processor extends AbstractHttp11Processor<Socket> {
     @Override
     protected void setRequestLineReadTimeout() throws IOException {
         
-        int standardTimeout = 0;
-        
-        if (keptAlive) {
-            if (keepAliveTimeout > 0) {
-                standardTimeout = keepAliveTimeout;
-            } else if (endpoint.getSoTimeout() > 0) {
-                standardTimeout = endpoint.getSoTimeout();
-            }
-        }
         /*
          * When there is no data in the buffer and this is not the first
          * request on this connection and timeouts are being used the
@@ -363,19 +354,23 @@ public class Http11Processor extends AbstractHttp11Processor<Socket> {
          * This is a little hacky but better than exposing the socket
          * and the timeout info to the InputBuffer
          */
-        if (inputBuffer.lastValid == 0 && socket.getLastAccess() > -1 &&
-                standardTimeout > 0) {
-
-            long queueTime = System.currentTimeMillis() - socket.getLastAccess();
+        if (inputBuffer.lastValid == 0 && socket.getLastAccess() > -1) {
             int firstReadTimeout;
-            if (queueTime >= standardTimeout) {
-                // Queued for longer than timeout but there might be
-                // data so use shortest possible timeout
-                firstReadTimeout = 1;
+            if (keepAliveTimeout == -1) {
+                firstReadTimeout = 0;
             } else {
-                // Cast is safe since queueTime must be less than
-                // standardTimeout which is an int
-                firstReadTimeout = standardTimeout - (int) queueTime;
+                long queueTime =
+                    System.currentTimeMillis() - socket.getLastAccess();
+
+                if (queueTime >= keepAliveTimeout) {
+                    // Queued for longer than timeout but there might be
+                    // data so use shortest possible timeout
+                    firstReadTimeout = 1;
+                } else {
+                    // Cast is safe since queueTime must be less than
+                    // keepAliveTimeout which is an int
+                    firstReadTimeout = keepAliveTimeout - (int) queueTime;
+                }
             }
             socket.getSocket().setSoTimeout(firstReadTimeout);
             if (!inputBuffer.fill()) {
index 54aad90..27ef98b 100644 (file)
@@ -170,12 +170,18 @@ public abstract class AbstractEndpoint {
     private BindState bindState = BindState.UNBOUND;
 
     /**
-     * Keepalive timeout, if lesser or equal to 0 then soTimeout will be used.
+     * Keepalive timeout, if not set the soTimeout is used.
      */
-    private int keepAliveTimeout = -1;
-    public int getKeepAliveTimeout() { return keepAliveTimeout;}
+    private Integer keepAliveTimeout = null;
+    public int getKeepAliveTimeout() {
+        if (keepAliveTimeout == null) {
+            return getSoTimeout();
+        } else {
+            return keepAliveTimeout.intValue();
+        }
+    }
     public void setKeepAliveTimeout(int keepAliveTimeout) {
-        this.keepAliveTimeout = keepAliveTimeout;
+        this.keepAliveTimeout = Integer.valueOf(keepAliveTimeout);
     }
 
 
index da5f863..7534cfb 100644 (file)
@@ -1129,7 +1129,7 @@ public class AprEndpoint extends AbstractEndpoint {
             int size = getMaxConnections() / pollerThreadCount;
             int keepAliveTimeout = getKeepAliveTimeout();
             int socketTimeout = socketProperties.getSoTimeout();
-            if (keepAliveTimeout > 0 && !comet) {
+            if (keepAliveTimeout != socketTimeout && !comet) {
                 separateKeepAlive = true;
             }
             connectionPollset = allocatePoller(size, pool, socketTimeout);
index 558cf55..ca8ba2d 100644 (file)
@@ -1340,7 +1340,7 @@ public class NioEndpoint extends AbstractEndpoint {
                               (ka.interestOps()&SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
                         //only timeout sockets that we are waiting for a read from
                         long delta = now - ka.getLastAccess();
-                        long timeout = (ka.getTimeout()==-1)?((long) socketProperties.getSoTimeout()):(ka.getTimeout());
+                        long timeout = ka.getTimeout();
                         boolean isTimedout = timeout > 0 && delta > timeout;
                         if ( close ) {
                             key.interestOps(0); 
@@ -1350,7 +1350,7 @@ public class NioEndpoint extends AbstractEndpoint {
                             key.interestOps(0); 
                             ka.interestOps(0); //avoid duplicate timeout calls
                             cancelledKey(key, SocketStatus.TIMEOUT,true);
-                        } else {
+                        } else if (timeout > -1) {
                             long nextTime = now+(timeout-delta);
                             nextExpiration = (nextTime < nextExpiration)?nextTime:nextExpiration;
                         }