You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/05/09 20:03:38 UTC

[09/35] httpcomponents-core git commit: HTTPCORE-261: IOSession#setSocketTimeout() method does not reset the timeout count (merged from trunk)

HTTPCORE-261: IOSession#setSocketTimeout() method does not reset the timeout count (merged from trunk)

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.1.x@1140270 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/a2c7e621
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/a2c7e621
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/a2c7e621

Branch: refs/heads/4.1.x
Commit: a2c7e6216c84ea944acf847c9ba5533ace032837
Parents: 5fff28b
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Mon Jun 27 19:06:14 2011 +0000
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Mon Jun 27 19:06:14 2011 +0000

----------------------------------------------------------------------
 RELEASE_NOTES.txt                               |  3 +
 .../impl/nio/reactor/AbstractIOReactor.java     | 57 ++++++++++++++-----
 .../http/impl/nio/reactor/BaseIOReactor.java    | 59 +++++---------------
 .../http/impl/nio/reactor/IOSessionImpl.java    | 42 +++++++++++++-
 .../http/impl/nio/reactor/SSLIOSession.java     |  5 +-
 .../http/impl/nio/reactor/SessionHandle.java    |  3 +
 .../http/nio/entity/SkipContentListener.java    |  3 -
 7 files changed, 107 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/RELEASE_NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 2c731d7..9ac0b52 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -1,6 +1,9 @@
 Changes since 4.1.1
 -------------------
 
+* [HTTPCORE-261] IOSession#setSocketTimeout() method does not reset the timeout count. 
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPCORE-260] Non-blocking SSL I/O session can terminate prematurely causing message body 
   truncation when message content is chunk coded and the connection is closed on the opposite end. 
   Contributed by Oleg Kalnichevski <olegk at apache.org>

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
index b75c6b2..d6f21e0 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
@@ -144,17 +144,6 @@ public abstract class AbstractIOReactor implements IOReactor {
     protected abstract void writable(SelectionKey key);
 
     /**
-     * Triggered to verify whether the I/O session associated with the
-     * given selection key has not timed out.
-     * <p>
-     * Super-classes can implement this method to react to the event.
-     *
-     * @param key the selection key.
-     * @param now current time as long value.
-     */
-    protected abstract void timeoutCheck(SelectionKey key, long now);
-
-    /**
      * Triggered to validate keys currently registered with the selector. This
      * method is called after each I/O select loop.
      * <p>
@@ -174,7 +163,8 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param key the selection key.
      * @param session new I/O session.
      */
-    protected abstract void sessionCreated(SelectionKey key, IOSession session);
+    protected void sessionCreated(final SelectionKey key, final IOSession session) {
+    }
 
     /**
      * Triggered when a session has been closed.
@@ -183,7 +173,18 @@ public abstract class AbstractIOReactor implements IOReactor {
      *
      * @param session closed I/O session.
      */
-    protected abstract void sessionClosed(IOSession session);
+    protected void sessionClosed(final IOSession session) {
+    }
+
+    /**
+     * Triggered when a session has timed out.
+     * <p>
+     * Super-classes can implement this method to react to the event.
+     *
+     * @param session timed out I/O session.
+     */
+    protected void sessionTimedOut(final IOSession session) {
+    }
 
     /**
      * Obtains {@link IOSession} instance associated with the given selection
@@ -192,7 +193,9 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param key the selection key.
      * @return I/O session.
      */
-    protected abstract IOSession getSession(SelectionKey key);
+    protected IOSession getSession(final SelectionKey key) {
+        return (IOSession) key.attachment();
+    }
 
     public IOReactorStatus getStatus() {
         return this.status;
@@ -324,6 +327,7 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param key the selection key that triggered an event.
      */
     protected void processEvent(final SelectionKey key) {
+        IOSessionImpl session = (IOSessionImpl) key.attachment();
         try {
             if (key.isAcceptable()) {
                 acceptable(key);
@@ -332,13 +336,14 @@ public abstract class AbstractIOReactor implements IOReactor {
                 connectable(key);
             }
             if (key.isReadable()) {
+                session.resetLastRead();
                 readable(key);
             }
             if (key.isWritable()) {
+                session.resetLastWrite();
                 writable(key);
             }
         } catch (CancelledKeyException ex) {
-            IOSession session = getSession(key);
             queueClosedSession(session);
             key.attach(null);
         }
@@ -416,6 +421,7 @@ public abstract class AbstractIOReactor implements IOReactor {
                 if (sessionRequest != null) {
                     sessionRequest.completed(session);
                 }
+                key.attach(session);
                 sessionCreated(key, session);
             } catch (CancelledKeyException ex) {
                 queueClosedSession(session);
@@ -469,6 +475,27 @@ public abstract class AbstractIOReactor implements IOReactor {
     }
 
     /**
+     * Triggered to verify whether the I/O session associated with the
+     * given selection key has not timed out.
+     * <p>
+     * Super-classes can implement this method to react to the event.
+     *
+     * @param key the selection key.
+     * @param now current time as long value.
+     */
+    protected void timeoutCheck(final SelectionKey key, long now) {
+        IOSessionImpl session = (IOSessionImpl) key.attachment();
+        if (session != null) {
+            int timeout = session.getSocketTimeout();
+            if (timeout > 0) {
+                if (session.getLastAccessTime() + timeout < now) {
+                    sessionTimedOut(session);
+                }
+            }
+        }
+    }
+
+    /**
      * Closes out all I/O sessions maintained by this I/O reactor.
      */
     protected void closeSessions() {

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
index 6e943e1..7676c00 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
@@ -109,7 +109,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      *
      * @param exceptionHandler the exception handler.
      */
-    public void setExceptionHandler(IOReactorExceptionHandler exceptionHandler) {
+    public void setExceptionHandler(final IOReactorExceptionHandler exceptionHandler) {
         this.exceptionHandler = exceptionHandler;
     }
 
@@ -153,10 +153,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     @Override
     protected void readable(final SelectionKey key) {
-        SessionHandle handle = (SessionHandle) key.attachment();
-        IOSession session = handle.getSession();
-        handle.resetLastRead();
-
+        IOSession session = getSession(key);
         try {
             this.eventDispatch.inputReady(session);
             if (session.hasBufferedInput()) {
@@ -177,10 +174,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     @Override
     protected void writable(final SelectionKey key) {
-        SessionHandle handle = (SessionHandle) key.attachment();
-        IOSession session = handle.getSession();
-        handle.resetLastWrite();
-
+        IOSession session = getSession(key);
         try {
             this.eventDispatch.outputReady(session);
         } catch (CancelledKeyException ex) {
@@ -247,57 +241,32 @@ public class BaseIOReactor extends AbstractIOReactor {
     }
 
     /**
-     * Performs timeout check for the I/O session associated with the given
-     * selection key.
-     */
-    @Override
-    protected void timeoutCheck(final SelectionKey key, long now) {
-        Object attachment = key.attachment();
-        if (attachment instanceof SessionHandle) {
-            SessionHandle handle = (SessionHandle) key.attachment();
-            IOSession session = handle.getSession();
-            int timeout = session.getSocketTimeout();
-            if (timeout > 0) {
-                if (handle.getLastAccessTime() + timeout < now) {
-                    try {
-                        this.eventDispatch.timeout(session);
-                    } catch (CancelledKeyException ex) {
-                        queueClosedSession(session);
-                        key.attach(null);
-                    } catch (RuntimeException ex) {
-                        handleRuntimeException(ex);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Processes newly created I/O session. This method dispatches the event
      * notification to the {@link IOEventDispatch#connected(IOSession)} method.
      */
     @Override
     protected void sessionCreated(final SelectionKey key, final IOSession session) {
-        SessionHandle handle = new SessionHandle(session);
-        key.attach(handle);
         try {
             this.eventDispatch.connected(session);
         } catch (CancelledKeyException ex) {
             queueClosedSession(session);
-            key.attach(null);
         } catch (RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
 
+    /**
+     * Processes timed out I/O session. This method dispatches the event
+     * notification to the {@link IOEventDispatch#timeout(IOSession)} method.
+     */
     @Override
-    protected IOSession getSession(final SelectionKey key) {
-        Object attachment = key.attachment();
-        if (attachment instanceof SessionHandle) {
-            SessionHandle handle = (SessionHandle) attachment;
-            return handle.getSession();
-        } else {
-            return null;
+    protected void sessionTimedOut(final IOSession session) {
+        try {
+            this.eventDispatch.timeout(session);
+        } catch (CancelledKeyException ex) {
+            queueClosedSession(session);
+        } catch (RuntimeException ex) {
+            handleRuntimeException(ex);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
index 97f0821..31e6682 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
@@ -58,6 +58,12 @@ public class IOSessionImpl implements IOSession {
     private volatile SessionBufferStatus bufferStatus;
     private volatile int socketTimeout;
 
+    private final long startedTime;
+
+    private long lastReadTime;
+    private long lastWriteTime;
+    private long lastAccessTime;
+
     /**
      * Creates new instance of IOSessionImpl.
      *
@@ -83,6 +89,11 @@ public class IOSessionImpl implements IOSession {
         this.currentEventMask = 0;
         this.socketTimeout = 0;
         this.status = ACTIVE;
+        long now = System.currentTimeMillis();
+        this.startedTime = now;
+        this.lastReadTime = now;
+        this.lastWriteTime = now;
+        this.lastAccessTime = now;
     }
 
     /**
@@ -186,8 +197,9 @@ public class IOSessionImpl implements IOSession {
         return this.socketTimeout;
     }
 
-    public void setSocketTimeout(int timeout) {
+    public synchronized void setSocketTimeout(int timeout) {
         this.socketTimeout = timeout;
+        this.lastAccessTime = System.currentTimeMillis();
     }
 
     public synchronized void close() {
@@ -250,6 +262,34 @@ public class IOSessionImpl implements IOSession {
         this.attributes.put(name, obj);
     }
 
+    synchronized long getStartedTime() {
+        return this.startedTime;
+    }
+
+    synchronized long getLastReadTime() {
+        return this.lastReadTime;
+    }
+
+    synchronized long getLastWriteTime() {
+        return this.lastWriteTime;
+    }
+
+    synchronized long getLastAccessTime() {
+        return this.lastAccessTime;
+    }
+
+    synchronized void resetLastRead() {
+        long now = System.currentTimeMillis();
+        this.lastReadTime = now;
+        this.lastAccessTime = now;
+    }
+
+    synchronized void resetLastWrite() {
+        long now = System.currentTimeMillis();
+        this.lastWriteTime = now;
+        this.lastAccessTime = now;
+    }
+
     private static void formatOps(final StringBuffer buffer, int ops) {
         if ((ops & SelectionKey.OP_READ) > 0) {
             buffer.append('r');

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
index 5e67cc2..8c0a488 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
@@ -235,6 +235,9 @@ public class SSLIOSession implements IOSession, SessionBufferStatus {
     }
 
     private int receiveEncryptedData() throws IOException {
+        if (this.endOfStream) {
+            return -1;
+        }
         return this.session.channel().read(this.inEncrypted);
     }
 
@@ -456,7 +459,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus {
         buffer.append("][");
         buffer.append(this.sslEngine.getHandshakeStatus());
         if (this.endOfStream) {
-            buffer.append("EOF][");
+            buffer.append("][EOF][");
         }
         buffer.append("][");
         buffer.append(this.inEncrypted.position());

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
index a9c7b30..09c308b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
@@ -34,8 +34,11 @@ import org.apache.http.nio.reactor.IOSession;
  * to a {@link IOSession} along with information about time of last I/O
  * operations on that session.
  *
+ * @deprecated use {@link IOSessionImpl}
+ *
  * @since 4.0
  */
+@Deprecated
 public class SessionHandle {
 
     private final IOSession session;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/a2c7e621/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
----------------------------------------------------------------------
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
index 06f654a..35b869b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
@@ -54,13 +54,10 @@ public class SkipContentListener implements ContentListener {
     public void contentAvailable(
             final ContentDecoder decoder,
             final IOControl ioctrl) throws IOException {
-        int totalRead = 0;
         int lastRead;
         do {
             buffer.clear();
             lastRead = decoder.read(buffer);
-            if (lastRead > 0)
-                totalRead += lastRead;
         } while (lastRead > 0);
     }