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 2019/09/26 20:38:04 UTC

[httpcomponents-core] 01/03: Added mechanism for low level i/o event handlers to push input data up the protocol processing chain instead of expecting the protocol handlers to consume it from the i/o session buffers

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 043de30cccfac419baa6abd26353db0a8d6844fb
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Fri Sep 13 11:31:00 2019 +0200

    Added mechanism for low level i/o event handlers to push input data up the protocol processing chain instead of expecting the protocol handlers to consume it from the i/o session buffers
---
 .../hc/core5/http2/impl/nio/AbstractH2IOEventHandler.java    |  7 ++++---
 .../hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java | 10 +++++-----
 .../core5/http2/impl/nio/ClientHttpProtocolNegotiator.java   |  2 +-
 .../core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java |  2 +-
 .../core5/http2/impl/nio/ServerHttpProtocolNegotiator.java   | 12 ++++++------
 .../hc/core5/testing/nio/TestDefaultListeningIOReactor.java  |  3 ++-
 .../hc/core5/http/impl/nio/AbstractHttp1IOEventHandler.java  |  7 ++++---
 .../hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java  | 10 +++++-----
 .../java/org/apache/hc/core5/reactor/IOEventHandler.java     |  3 ++-
 .../org/apache/hc/core5/reactor/InternalDataChannel.java     |  2 +-
 .../apache/hc/core5/reactor/SocksProxyProtocolHandler.java   | 10 +++++++++-
 .../java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java   |  5 ++---
 12 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2IOEventHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2IOEventHandler.java
index 0195bb0..9dcd38e 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2IOEventHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2IOEventHandler.java
@@ -29,6 +29,7 @@ package org.apache.hc.core5.http2.impl.nio;
 
 import java.io.IOException;
 import java.net.SocketAddress;
+import java.nio.ByteBuffer;
 
 import javax.net.ssl.SSLSession;
 
@@ -52,16 +53,16 @@ class AbstractH2IOEventHandler implements HttpConnectionEventHandler {
     @Override
     public void connected(final IOSession session) throws IOException {
         try {
-            streamMultiplexer.onConnect(null);
+            streamMultiplexer.onConnect();
         } catch (final HttpException ex) {
             streamMultiplexer.onException(ex);
         }
     }
 
     @Override
-    public void inputReady(final IOSession session) throws IOException {
+    public void inputReady(final IOSession session, final ByteBuffer src) throws IOException {
         try {
-            streamMultiplexer.onInput();
+            streamMultiplexer.onInput(src);
         } catch (final HttpException ex) {
             streamMultiplexer.onException(ex);
         }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
index fdfa55d..831114b 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
@@ -398,10 +398,7 @@ abstract class AbstractH2StreamMultiplexer implements Identifiable, HttpConnecti
         }
     }
 
-    public final void onConnect(final ByteBuffer prefeed) throws HttpException, IOException {
-        if (prefeed != null) {
-            inputBuffer.put(prefeed);
-        }
+    public final void onConnect() throws HttpException, IOException {
         connState = ConnectionHandshake.ACTIVE;
         final RawFrame settingsFrame = frameFactory.createSettings(
                 new H2Setting(H2Param.HEADER_TABLE_SIZE, localConfig.getHeaderTableSize()),
@@ -415,10 +412,13 @@ abstract class AbstractH2StreamMultiplexer implements Identifiable, HttpConnecti
         localSettingState = SettingsHandshake.TRANSMITTED;
     }
 
-    public final void onInput() throws HttpException, IOException {
+    public final void onInput(final ByteBuffer src) throws HttpException, IOException {
         if (connState == ConnectionHandshake.SHUTDOWN) {
             ioSession.clearEvent(SelectionKey.OP_READ);
         } else {
+            if (src != null) {
+                inputBuffer.put(src);
+            }
             RawFrame frame;
             while ((frame = inputBuffer.read(ioSession)) != null) {
                 if (streamListener != null) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
index 8e6e346..b1da774 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
@@ -153,7 +153,7 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
     }
 
     @Override
-    public void inputReady(final IOSession session) throws IOException  {
+    public void inputReady(final IOSession session, final ByteBuffer src) throws IOException  {
         outputReady(session);
     }
 
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
index 0decbf0..94a145f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
@@ -114,7 +114,7 @@ public class H2OnlyClientProtocolNegotiator implements HttpConnectionEventHandle
     }
 
     @Override
-    public void inputReady(final IOSession session) {
+    public void inputReady(final IOSession session, final ByteBuffer src) {
         outputReady(session);
     }
 
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
index 157efe1..4a85534 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
@@ -113,7 +113,7 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                     final HttpConnectionEventHandler protocolHandler = new ServerHttp1IOEventHandler(http1StreamHandler);
                     ioSession.upgrade(protocolHandler);
                     protocolHandlerRef.set(protocolHandler);
-                    http1StreamHandler.onConnect(null);
+                    http1StreamHandler.onConnect();
                     break;
             }
         } catch (final Exception ex) {
@@ -122,7 +122,7 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
     }
 
     @Override
-    public void inputReady(final IOSession session) {
+    public void inputReady(final IOSession session, final ByteBuffer src) {
         try {
             boolean endOfStream = false;
             if (bytebuf.position() < PREFACE.length) {
@@ -148,8 +148,8 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                     final HttpConnectionEventHandler protocolHandler = new ServerH2IOEventHandler(http2StreamHandler);
                     ioSession.upgrade(protocolHandler);
                     protocolHandlerRef.set(protocolHandler);
-                    http2StreamHandler.onConnect(bytebuf.hasRemaining() ? bytebuf : null);
-                    http2StreamHandler.onInput();
+                    http2StreamHandler.onConnect();
+                    http2StreamHandler.onInput(bytebuf.hasRemaining() ? bytebuf : null);
                 } else {
                     final TlsDetails tlsDetails = ioSession.getTlsDetails();
                     final ServerHttp1StreamDuplexer http1StreamHandler = http1StreamHandlerFactory.create(
@@ -159,8 +159,8 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                     ioSession.upgrade(protocolHandler);
                     protocolHandlerRef.set(protocolHandler);
                     bytebuf.rewind();
-                    http1StreamHandler.onConnect(bytebuf);
-                    http1StreamHandler.onInput();
+                    http1StreamHandler.onConnect();
+                    http1StreamHandler.onInput(bytebuf);
                 }
             } else {
                 if (endOfStream) {
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TestDefaultListeningIOReactor.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TestDefaultListeningIOReactor.java
index 73fc912..0bfea82 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TestDefaultListeningIOReactor.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TestDefaultListeningIOReactor.java
@@ -28,6 +28,7 @@
 package org.apache.hc.core5.testing.nio;
 
 import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -66,7 +67,7 @@ public class TestDefaultListeningIOReactor {
                 }
 
                 @Override
-                public void inputReady(final IOSession session) {
+                public void inputReady(final IOSession session, final ByteBuffer src) {
                 }
 
                 @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1IOEventHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1IOEventHandler.java
index 81211fa..8f89d80 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1IOEventHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1IOEventHandler.java
@@ -29,6 +29,7 @@ package org.apache.hc.core5.http.impl.nio;
 
 import java.io.IOException;
 import java.net.SocketAddress;
+import java.nio.ByteBuffer;
 
 import javax.net.ssl.SSLSession;
 
@@ -51,16 +52,16 @@ class AbstractHttp1IOEventHandler implements HttpConnectionEventHandler {
     @Override
     public void connected(final IOSession session) throws IOException {
         try {
-            streamDuplexer.onConnect(null);
+            streamDuplexer.onConnect();
         } catch (final HttpException ex) {
             streamDuplexer.onException(ex);
         }
     }
 
     @Override
-    public void inputReady(final IOSession session) throws IOException {
+    public void inputReady(final IOSession session, final ByteBuffer src) throws IOException {
         try {
-            streamDuplexer.onInput();
+            streamDuplexer.onInput(src);
         } catch (final HttpException ex) {
             streamDuplexer.onException(ex);
         }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
index 3b21997..6860bd3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
@@ -229,15 +229,15 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
         }
     }
 
-    public final void onConnect(final ByteBuffer prefeed) throws HttpException, IOException {
-        if (prefeed != null) {
-            inbuf.put(prefeed);
-        }
+    public final void onConnect() throws HttpException, IOException {
         connState = ConnectionState.ACTIVE;
         processCommands();
     }
 
-    public final void onInput() throws HttpException, IOException {
+    public final void onInput(final ByteBuffer src) throws HttpException, IOException {
+        if (src != null) {
+            inbuf.put(src);
+        }
         while (connState.compareTo(ConnectionState.SHUTDOWN) < 0) {
             int totalBytesRead = 0;
             int messagesReceived = 0;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOEventHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOEventHandler.java
index 52cfb5c..b747ef2 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOEventHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOEventHandler.java
@@ -28,6 +28,7 @@
 package org.apache.hc.core5.reactor;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
 
 import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.util.Timeout;
@@ -56,7 +57,7 @@ public interface IOEventHandler {
      *
      * @param session the I/O session.
      */
-    void inputReady(IOSession session) throws IOException;
+    void inputReady(IOSession session, ByteBuffer src) throws IOException;
 
     /**
      * Triggered when the given session is ready for output.
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index 356202a..7fce8aa 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -121,7 +121,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
                 sessionListener.inputReady(this);
             }
             final IOEventHandler handler = ensureHandler(currentSession);
-            handler.inputReady(this);
+            handler.inputReady(this, null);
         }
         if ((readyOps & SelectionKey.OP_WRITE) != 0
                 || (ioSession.getEventMask() & SelectionKey.OP_WRITE) != 0) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
index ed55892..73fd246 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
@@ -32,6 +32,7 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
@@ -138,7 +139,14 @@ final class SocksProxyProtocolHandler implements IOEventHandler {
     }
 
     @Override
-    public void inputReady(final IOSession session) throws IOException {
+    public void inputReady(final IOSession session, final ByteBuffer src) throws IOException {
+        if (src != null) {
+            try {
+                this.buffer.put(src);
+            } catch (final BufferOverflowException ex) {
+                throw new IOException("Unexpected input data");
+            }
+        }
         switch (this.state) {
             case RECEIVE_AUTH_METHOD:
                 if (fillBuffer(session)) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
index 5574639..7197429 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
@@ -180,13 +180,13 @@ public class SSLIOSession implements IOSession {
             }
 
             @Override
-            public void inputReady(final IOSession protocolSession) throws IOException {
+            public void inputReady(final IOSession protocolSession, final ByteBuffer src) throws IOException {
                 ensureInitialized();
                 do {
                     bytesReadCount.set(0L);
                     if (isAppInputReady()) {
                         final IOEventHandler handler = ensureHandler();
-                        handler.inputReady(protocolSession);
+                        handler.inputReady(protocolSession, src);
                     }
                     inboundTransport();
                 } while (bytesReadCount.get() > 0);
@@ -286,7 +286,6 @@ public class SSLIOSession implements IOSession {
 
             this.inEncrypted.release();
             this.outEncrypted.release();
-            this.inPlain.release();
             doHandshake();
         } finally {
             this.session.getLock().unlock();