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 2016/10/31 17:33:33 UTC

svn commit: r1767339 [3/14] - in /httpcomponents/httpcore/trunk: ./ httpcore5-ab/src/main/java/org/apache/hc/core5/http/benchmark/ httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/ httpcore5-h2/src/main/java/org/apache/hc/core5/http2/boots...

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/LoggingBHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/LoggingBHttpServerConnection.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/LoggingBHttpServerConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/LoggingBHttpServerConnection.java Mon Oct 31 17:33:27 2016
@@ -43,7 +43,7 @@ import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.config.MessageConstraints;
+import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
 import org.apache.hc.core5.http.io.HttpMessageParserFactory;
 import org.apache.hc.core5.http.io.HttpMessageWriterFactory;
@@ -64,7 +64,7 @@ public class LoggingBHttpServerConnectio
             final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
-            final MessageConstraints constraints,
+            final H1Config constraints,
             final ContentLengthStrategy incomingContentStrategy,
             final ContentLengthStrategy outgoingContentStrategy,
             final HttpMessageParserFactory<ClassicHttpRequest> requestParserFactory,

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/Wire.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/Wire.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/Wire.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/Wire.java Mon Oct 31 17:33:27 2016
@@ -27,9 +27,11 @@
 
 package org.apache.hc.core5.testing.classic;
 
+import java.nio.ByteBuffer;
+
 import org.apache.commons.logging.Log;
 
-class Wire {
+public class Wire {
 
     private final Log log;
     private final String id;
@@ -74,11 +76,11 @@ class Wire {
     }
 
     public void output(final byte[] b, final int pos, final int off) {
-        wire("<< ", b, pos, off);
+        wire(">> ", b, pos, off);
     }
 
     public void input(final byte[] b, final int pos, final int off) {
-        wire(">> ", b, pos, off);
+        wire("<< ", b, pos, off);
     }
 
     public void output(final byte[] b) {
@@ -97,4 +99,24 @@ class Wire {
         input(new byte[] {(byte) b});
     }
 
+    public void output(final ByteBuffer b) {
+        if (b.hasArray()) {
+            output(b.array(), b.arrayOffset() + b.position(), b.remaining());
+        } else {
+            final byte[] tmp = new byte[b.remaining()];
+            b.get(tmp);
+            output(tmp);
+        }
+    }
+
+    public void input(final ByteBuffer b) {
+        if (b.hasArray()) {
+            input(b.array(), b.arrayOffset() + b.position(), b.remaining());
+        } else {
+            final byte[] tmp = new byte[b.remaining()];
+            b.get(tmp);
+            input(tmp);
+        }
+    }
+
 }

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClassicTestClientAdapter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClassicTestClientAdapter.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClassicTestClientAdapter.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClassicTestClientAdapter.java Mon Oct 31 17:33:27 2016
@@ -38,10 +38,10 @@ import org.apache.hc.core5.http.HttpEnti
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.http.entity.ContentType;
-import org.apache.hc.core5.http.entity.EntityUtils;
-import org.apache.hc.core5.http.entity.StringEntity;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection;
+import org.apache.hc.core5.http.io.entity.ContentType;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
 import org.apache.hc.core5.testing.classic.ClassicTestClient;
 
@@ -136,7 +136,7 @@ public class ClassicTestClientAdapter ex
             client.setTimeout((int) timeout);
         }
 
-        // Now execute the request.
+        // Now start the request.
         final DefaultBHttpClientConnection conn = client.createConnection();
         final HttpHost host = new HttpHost(uri.getHost(), uri.getPort());
 

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientPOJOAdapter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientPOJOAdapter.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientPOJOAdapter.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientPOJOAdapter.java Mon Oct 31 17:33:27 2016
@@ -109,7 +109,7 @@ public abstract class ClientPOJOAdapter
      * a particular request, a non-null reason should be returned.  Otherwise, if
      * the request is supported, return null.</p>
      *
-     * <p>If this method is overridden, then the execute method should probably call
+     * <p>If this method is overridden, then the start method should probably call
      * assertRequestSupported() at the beginning.</p>
      *
      * @param request the request as specified above.
@@ -123,7 +123,7 @@ public abstract class ClientPOJOAdapter
     /**
      * <p>Assert that the request is supported</p>
      *
-     * <p>Usually called by the execute method.  Throws an exception if the request
+     * <p>Usually called by the start method.  Throws an exception if the request
      * is not supported.</p>
      *
      * @param request the request as specified above.
@@ -144,7 +144,7 @@ public abstract class ClientPOJOAdapter
      * special request handler of the in-process HttpServer which will later check
      * an actual HTTP request against what is expected.</p>
      *
-     * <p>In a production context, this is called by the execute method (if at all).</p>
+     * <p>In a production context, this is called by the start method (if at all).</p>
      *
      * @param request the request as specified above.
      * @return the same request or a modification of it.

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientTestingAdapter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientTestingAdapter.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientTestingAdapter.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/ClientTestingAdapter.java Mon Oct 31 17:33:27 2016
@@ -44,7 +44,7 @@ import java.util.Map;
 *
 * isRequestSupported
 * modifyRequest
-* execute
+* start
 *
 * </pre>
 *
@@ -67,8 +67,8 @@ public class ClientTestingAdapter {
 
     /*
      * The following is not expected to be changed to true, but it is to highlight
-     * where the execute method can call the requestHandler's assertNothingThrown()
-     * method if desired.  Since this adapter's execute method does not check
+     * where the start method can call the requestHandler's assertNothingThrown()
+     * method if desired.  Since this adapter's start method does not check
      * the response, there is no need to call it.
      */
     protected boolean callAssertNothingThrown;
@@ -88,17 +88,17 @@ public class ClientTestingAdapter {
      * it can optionally call assertNothingThrown() before checking the response
      * further.  It is optional because the test framework will call it later.
      *
-     * @param defaultURI           See execute method of {@link ClientPOJOAdapter}.
-     * @param request              See execute method of {@link ClientPOJOAdapter}.
+     * @param defaultURI           See start method of {@link ClientPOJOAdapter}.
+     * @param request              See start method of {@link ClientPOJOAdapter}.
      * @param requestHandler       The request handler that checks the received HTTP request
      *                             with the request that was intended.  If there is a
      *                             mismatch of expectations, then the requestHandler will
-     *                             throw an exception.  If this execute method does not want
+     *                             throw an exception.  If this start method does not want
      *                             to make further checks of the response in the case
      *                             the responseHandler threw, then the assertNothingThrown()
      *                             method should be called before doing further checks.
      * @param responseExpectations The response expectations of the test.
-     * @return See return of the execute method of {@link ClientPOJOAdapter}.
+     * @return See return of the start method of {@link ClientPOJOAdapter}.
      * @throws TestingFrameworkException in the case of a problem.
      */
     public Map<String, Object> execute(final String defaultURI, final Map<String, Object> request,
@@ -109,7 +109,7 @@ public class ClientTestingAdapter {
             if (adapter == null) {
                 throw new TestingFrameworkException("adapter cannot be null");
             }
-            // Call the adapter's execute method to actually make the HTTP request.
+            // Call the adapter's start method to actually make the HTTP request.
             final Map<String, Object> response = adapter.execute(defaultURI, request);
 
             /*

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java Mon Oct 31 17:33:27 2016
@@ -50,9 +50,9 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.http.bootstrap.io.HttpServer;
-import org.apache.hc.core5.http.bootstrap.io.ServerBootstrap;
 import org.apache.hc.core5.http.config.SocketConfig;
+import org.apache.hc.core5.http.impl.io.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.io.bootstrap.ServerBootstrap;
 
 /**
  * <p>This testing framework starts an in-process {@link HttpServer} which will use an

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFrameworkRequestHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFrameworkRequestHandler.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFrameworkRequestHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFrameworkRequestHandler.java Mon Oct 31 17:33:27 2016
@@ -50,10 +50,10 @@ import org.apache.hc.core5.http.HttpEnti
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.NameValuePair;
 import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.http.entity.ContentType;
-import org.apache.hc.core5.http.entity.EntityUtils;
-import org.apache.hc.core5.http.entity.StringEntity;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.entity.ContentType;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.util.URLEncodedUtils;
 

Added: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java?rev=1767339&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java Mon Oct 31 17:33:27 2016
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.testing.nio;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+import org.apache.commons.logging.Log;
+import org.apache.hc.core5.http.HttpConnectionMetrics;
+import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
+import org.apache.hc.core5.reactor.IOSession;
+
+public class LoggingIOEventHandler implements HttpConnectionEventHandler {
+
+    private final HttpConnectionEventHandler handler;
+    private final String id;
+    private final Log log;
+
+    public LoggingIOEventHandler(
+            final HttpConnectionEventHandler handler,
+            final String id,
+            final Log log) {
+        super();
+        this.handler = handler;
+        this.id = id;
+        this.log = log;
+    }
+
+    @Override
+    public void connected(final IOSession session) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " " + session + " connected");
+        }
+        handler.connected(session);
+    }
+
+    @Override
+    public void inputReady(final IOSession session) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " " + session + " input ready");
+        }
+        handler.inputReady(session);
+    }
+
+    @Override
+    public void outputReady(final IOSession session) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " " + session + " output ready");
+        }
+        handler.outputReady(session);
+    }
+
+    @Override
+    public void timeout(final IOSession session) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " " + session + " timeout");
+        }
+        handler.timeout(session);
+    }
+
+    @Override
+    public void disconnected(final IOSession session) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " " + session + " disconnected");
+        }
+        handler.disconnected(session);
+    }
+
+    @Override
+    public HttpConnectionMetrics getMetrics() {
+        return handler.getMetrics();
+    }
+
+    @Override
+    public void setSocketTimeout(final int timeout) {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " set timeout " + timeout);
+        }
+        handler.setSocketTimeout(timeout);
+    }
+
+    @Override
+    public int getSocketTimeout() {
+        return handler.getSocketTimeout();
+    }
+
+    @Override
+    public ProtocolVersion getProtocolVersion() {
+        return handler.getProtocolVersion();
+    }
+
+    @Override
+    public SocketAddress getRemoteAddress() {
+        return handler.getRemoteAddress();
+    }
+
+    @Override
+    public SocketAddress getLocalAddress() {
+        return handler.getLocalAddress();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return handler.isOpen();
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " close");
+        }
+        handler.close();
+    }
+
+    @Override
+    public void shutdown() throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug(id + " shutdown");
+        }
+        handler.shutdown();
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOEventHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java (from r1765384, httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/testserver/nio/LoggingIOSession.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java?p2=httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java&p1=httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/testserver/nio/LoggingIOSession.java&r1=1765384&r2=1767339&rev=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/testserver/nio/LoggingIOSession.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java Mon Oct 31 17:33:27 2016
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.hc.core5.http.testserver.nio;
+package org.apache.hc.core5.testing.nio;
 
 import java.io.IOException;
 import java.net.SocketAddress;
@@ -35,6 +35,7 @@ import java.nio.channels.SelectionKey;
 import java.util.Deque;
 
 import org.apache.commons.logging.Log;
+import org.apache.hc.core5.testing.classic.Wire;
 import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOSession;
@@ -56,10 +57,14 @@ public class LoggingIOSession implements
     public LoggingIOSession(final IOSession session, final String id, final Log log, final Log wirelog) {
         super();
         this.session = session;
-        this.channel = new LoggingByteChannel();
         this.id = id;
         this.log = log;
-        this.wirelog = new Wire(wirelog, this.id);
+        this.wirelog = wirelog != null ? new Wire(wirelog, this.id) : null;
+        this.channel = wirelog != null ? new LoggingByteChannel() : session.channel();
+    }
+
+    public LoggingIOSession(final IOSession session, final String id, final Log log) {
+        this(session, id, log, null);
     }
 
     @Override

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Mon Oct 31 17:33:27 2016
@@ -0,0 +1 @@
+/httpcomponents/httpcore/branches/ibm_compat_branch/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingIOSession.java:755687-758898

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java?rev=1767339&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java Mon Oct 31 17:33:27 2016
@@ -0,0 +1,162 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.testing.nio.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
+import java.nio.channels.SelectionKey;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hc.core5.concurrent.BasicFuture;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.config.ConnectionConfig;
+import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.hc.core5.http.impl.HttpProcessors;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncRequester;
+import org.apache.hc.core5.http.impl.nio.bootstrap.ClientEndpoint;
+import org.apache.hc.core5.http.impl.nio.bootstrap.ClientEndpointImpl;
+import org.apache.hc.core5.http.nio.command.ShutdownCommand;
+import org.apache.hc.core5.http.nio.command.ShutdownType;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.reactor.IOSessionCallback;
+import org.apache.hc.core5.reactor.SessionRequest;
+import org.apache.hc.core5.reactor.SessionRequestCallback;
+
+public class Http1TestClient extends AsyncRequester {
+
+    public Http1TestClient(final IOReactorConfig ioReactorConfig) throws IOException {
+        super(ioReactorConfig, new ExceptionListener() {
+
+            private final Log log = LogFactory.getLog(Http1TestClient.class);
+
+            @Override
+            public void onError(final Exception ex) {
+                log.error(ex.getMessage(), ex);
+            }
+
+        }, new IOSessionCallback() {
+            @Override
+            public void execute(final IOSession session) throws IOException {
+                session.getCommandQueue().addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
+                session.setEvent(SelectionKey.OP_WRITE);
+            }
+        });
+    }
+
+    public Http1TestClient() throws IOException {
+        this(IOReactorConfig.DEFAULT);
+    }
+
+    public void start(
+            final HttpProcessor httpProcessor,
+            final H1Config h1Config,
+            final ConnectionConfig connectionConfig) throws IOException {
+        execute(new InternalClientHttp1EventHandlerFactory(
+                httpProcessor,
+                h1Config,
+                connectionConfig,
+                DefaultConnectionReuseStrategy.INSTANCE));
+    }
+
+    public void start(final H1Config h1Config, final ConnectionConfig connectionConfig) throws IOException {
+        start(HttpProcessors.client(), h1Config, connectionConfig);
+    }
+
+    public void start(final H1Config h1Config) throws IOException {
+        start(h1Config, ConnectionConfig.DEFAULT);
+    }
+
+    public void start() throws IOException {
+        start(H1Config.DEFAULT);
+    }
+
+    @Override
+    public SessionRequest requestSession(
+            final InetSocketAddress address,
+            final long timeout,
+            final TimeUnit timeUnit,
+            final SessionRequestCallback callback) throws InterruptedException {
+        return super.requestSession(address, timeout, timeUnit, callback);
+    }
+
+    public Future<ClientEndpoint> connect(
+            final InetSocketAddress address,
+            final long timeout,
+            final TimeUnit timeUnit,
+            final FutureCallback<ClientEndpoint> callback) throws InterruptedException {
+        final BasicFuture<ClientEndpoint> future = new BasicFuture<>(callback);
+        requestSession(address, timeout, timeUnit, new SessionRequestCallback() {
+
+            @Override
+            public void completed(final SessionRequest request) {
+                final IOSession session = request.getSession();
+                future.completed(new ClientEndpointImpl(session));
+            }
+
+            @Override
+            public void failed(final SessionRequest request) {
+                future.failed(request.getException());
+            }
+
+            @Override
+            public void timeout(final SessionRequest request) {
+                future.failed(new SocketTimeoutException("Connect timeout"));
+            }
+
+            @Override
+            public void cancelled(final SessionRequest request) {
+                future.cancel();
+            }
+        });
+        return future;
+    }
+
+    public Future<ClientEndpoint> connect(
+            final InetSocketAddress address,
+            final long timeout,
+            final TimeUnit timeUnit) throws InterruptedException {
+        return connect(address, timeout, timeUnit, null);
+    }
+
+    public Future<ClientEndpoint> connect(
+            final String hostname,
+            final int port,
+            final long timeout,
+            final TimeUnit timeUnit) throws InterruptedException {
+        return connect(new InetSocketAddress(hostname, port), timeout, timeUnit);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestClient.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java?rev=1767339&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java Mon Oct 31 17:33:27 2016
@@ -0,0 +1,125 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.testing.nio.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SelectionKey;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.config.ConnectionConfig;
+import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.hc.core5.http.impl.HttpProcessors;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncServer;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncServerExchangeHandlerRegistry;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.Supplier;
+import org.apache.hc.core5.http.nio.command.ShutdownCommand;
+import org.apache.hc.core5.http.nio.command.ShutdownType;
+import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.RequestConsumerSupplier;
+import org.apache.hc.core5.http.nio.support.ResponseHandler;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.reactor.IOEventHandlerFactory;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.reactor.IOSessionCallback;
+import org.apache.hc.core5.reactor.ListenerEndpoint;
+
+public class Http1TestServer extends AsyncServer {
+
+    private final AsyncServerExchangeHandlerRegistry handlerRegistry;
+
+    public Http1TestServer(final IOReactorConfig ioReactorConfig) throws IOException {
+        super(ioReactorConfig, new ExceptionListener() {
+
+            private final Log log = LogFactory.getLog(Http1TestServer.class);
+
+            @Override
+            public void onError(final Exception ex) {
+                log.error(ex.getMessage(), ex);
+            }
+
+        }, new IOSessionCallback() {
+
+            @Override
+            public void execute(final IOSession session) throws IOException {
+                session.getCommandQueue().addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
+                session.setEvent(SelectionKey.OP_WRITE);
+            }
+
+        });
+        this.handlerRegistry = new AsyncServerExchangeHandlerRegistry("localhost");
+    }
+
+    public Http1TestServer() throws IOException {
+        this(IOReactorConfig.DEFAULT);
+    }
+
+    public void register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
+        handlerRegistry.register(null, uriPattern, supplier);
+    }
+
+    public <T> void register(
+            final String uriPattern,
+            final RequestConsumerSupplier<T> consumerSupplier,
+            final ResponseHandler<T> responseHandler) {
+        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+            }
+
+        });
+    }
+
+    public InetSocketAddress start(final IOEventHandlerFactory handlerFactory) throws Exception {
+        execute(handlerFactory);
+        final ListenerEndpoint listener = listen(new InetSocketAddress(0));
+        listener.waitFor();
+        return (InetSocketAddress) listener.getAddress();
+    }
+
+    public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
+        return start(new InternalServerHttp1EventHandlerFactory(
+                httpProcessor,
+                handlerRegistry,
+                h1Config,
+                ConnectionConfig.DEFAULT,
+                DefaultConnectionReuseStrategy.INSTANCE));
+    }
+
+    public InetSocketAddress start() throws Exception {
+        return start(HttpProcessors.server(), H1Config.DEFAULT);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/Http1TestServer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java?rev=1767339&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java Mon Oct 31 17:33:27 2016
@@ -0,0 +1,192 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.testing.nio.http;
+
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.ConnectionReuseStrategy;
+import org.apache.hc.core5.http.ContentLengthStrategy;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpConnection;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.config.ConnectionConfig;
+import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
+import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
+import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer;
+import org.apache.hc.core5.http.impl.nio.ConnectionListener;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestWriterFactory;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpResponseParserFactory;
+import org.apache.hc.core5.http.impl.nio.Http1StreamListener;
+import org.apache.hc.core5.http.message.RequestLine;
+import org.apache.hc.core5.http.message.StatusLine;
+import org.apache.hc.core5.http.nio.NHttpMessageParser;
+import org.apache.hc.core5.http.nio.NHttpMessageWriter;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.reactor.IOEventHandler;
+import org.apache.hc.core5.reactor.IOEventHandlerFactory;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.testing.nio.LoggingIOEventHandler;
+import org.apache.hc.core5.testing.nio.LoggingIOSession;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+class InternalClientHttp1EventHandlerFactory implements IOEventHandlerFactory {
+
+    private static final AtomicLong COUNT = new AtomicLong();
+
+    private final HttpProcessor httpProcessor;
+    private final H1Config h1Config;
+    private final ConnectionConfig connectionConfig;
+    private final ConnectionReuseStrategy connectionReuseStrategy;
+
+    InternalClientHttp1EventHandlerFactory(
+            final HttpProcessor httpProcessor,
+            final H1Config h1Config,
+            final ConnectionConfig connectionConfig,
+            final ConnectionReuseStrategy connectionReuseStrategy) {
+        this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
+        this.h1Config = h1Config != null ? h1Config : H1Config.DEFAULT;
+        this.connectionConfig = connectionConfig != null ? connectionConfig: ConnectionConfig.DEFAULT;
+        this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
+                DefaultConnectionReuseStrategy.INSTANCE;
+    }
+
+    protected ClientHttp1StreamDuplexer createClientHttp1StreamDuplexer(
+            final IOSession ioSession,
+            final HttpProcessor httpProcessor,
+            final H1Config h1Config,
+            final ConnectionConfig connectionConfig,
+            final ConnectionReuseStrategy connectionReuseStrategy,
+            final NHttpMessageParser<HttpResponse> incomingMessageParser,
+            final NHttpMessageWriter<HttpRequest> outgoingMessageWriter,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final ConnectionListener connectionListener,
+            final Http1StreamListener streamListener) {
+        return new ClientHttp1StreamDuplexer(ioSession, httpProcessor, h1Config, connectionConfig,
+                connectionReuseStrategy, incomingMessageParser, outgoingMessageWriter,
+                incomingContentStrategy, outgoingContentStrategy,
+                connectionListener, streamListener);
+    }
+
+    @Override
+    public IOEventHandler createHandler(final IOSession ioSession) {
+        final String id = "http1-outgoing-" + COUNT.incrementAndGet();
+        final Log sessionLog = LogFactory.getLog(ioSession.getClass());
+        final Log wireLog = LogFactory.getLog("org.apache.hc.core5.http.wire");
+        final Log headerLog = LogFactory.getLog("org.apache.hc.core5.http.headers");
+        final ClientHttp1StreamDuplexer streamDuplexer = createClientHttp1StreamDuplexer(
+                new LoggingIOSession(ioSession, id, sessionLog, wireLog),
+                httpProcessor,
+                h1Config,
+                connectionConfig,
+                connectionReuseStrategy,
+                DefaultHttpResponseParserFactory.INSTANCE.create(h1Config),
+                DefaultHttpRequestWriterFactory.INSTANCE.create(),
+                DefaultContentLengthStrategy.INSTANCE,
+                DefaultContentLengthStrategy.INSTANCE,
+                new ConnectionListener() {
+
+                    @Override
+                    public void onConnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " connected");
+                        }
+                    }
+
+                    @Override
+                    public void onDisconnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " disconnected");
+                        }
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection connection, final Exception ex) {
+                        if (ex instanceof ConnectionClosedException) {
+                            return;
+                        }
+                        sessionLog.error(id + ": "  + ex.getMessage(), ex);
+                    }
+
+                },
+                new Http1StreamListener() {
+
+                    @Override
+                    public void onRequestHead(final HttpConnection connection, final HttpRequest request) {
+                        if (headerLog.isDebugEnabled()) {
+                            headerLog.debug(id + " >> " + new RequestLine(request.getMethod(), request.getPath(),
+                                    request.getVersion() != null ? request.getVersion() : HttpVersion.HTTP_1_1));
+                            for (final Iterator<Header> it = request.headerIterator(); it.hasNext(); ) {
+                                headerLog.debug(id + " >> " + it.next());
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onResponseHead(final HttpConnection connection, final HttpResponse response) {
+                        if (headerLog.isDebugEnabled()) {
+                            headerLog.debug(id + " << " + new StatusLine(
+                                    response.getVersion() != null ? response.getVersion() : HttpVersion.HTTP_1_1,
+                                    response.getCode(), response.getReasonPhrase()));
+                            for (final Iterator<Header> it = response.headerIterator(); it.hasNext(); ) {
+                                headerLog.debug(id + " << " + it.next());
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onExchangeComplete(final HttpConnection connection, final boolean keepAlive) {
+                        if (sessionLog.isDebugEnabled()) {
+                            if (keepAlive) {
+                                sessionLog.debug(id + " Connection is kept alive");
+                            } else {
+                                sessionLog.debug(id + " Connection is not kept alive");
+                            }
+                        }
+                    }
+
+                });
+
+        return new LoggingIOEventHandler(new ClientHttp1IOEventHandler(streamDuplexer), id, sessionLog);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalClientHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java?rev=1767339&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java Mon Oct 31 17:33:27 2016
@@ -0,0 +1,199 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.testing.nio.http;
+
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.ConnectionReuseStrategy;
+import org.apache.hc.core5.http.ContentLengthStrategy;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpConnection;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.config.ConnectionConfig;
+import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
+import org.apache.hc.core5.http.impl.nio.ConnectionListener;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestParserFactory;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpResponseWriterFactory;
+import org.apache.hc.core5.http.impl.nio.Http1StreamListener;
+import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandler;
+import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer;
+import org.apache.hc.core5.http.message.RequestLine;
+import org.apache.hc.core5.http.message.StatusLine;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.nio.NHttpMessageParser;
+import org.apache.hc.core5.http.nio.NHttpMessageWriter;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.reactor.IOEventHandler;
+import org.apache.hc.core5.reactor.IOEventHandlerFactory;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.testing.nio.LoggingIOEventHandler;
+import org.apache.hc.core5.testing.nio.LoggingIOSession;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+class InternalServerHttp1EventHandlerFactory implements IOEventHandlerFactory {
+
+    private static final AtomicLong COUNT = new AtomicLong();
+
+    private final HttpProcessor httpProcessor;
+    private final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory;
+    private final H1Config h1Config;
+    private final ConnectionConfig connectionConfig;
+    private final ConnectionReuseStrategy connectionReuseStrategy;
+
+    InternalServerHttp1EventHandlerFactory(
+            final HttpProcessor httpProcessor,
+            final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory,
+            final H1Config h1Config,
+            final ConnectionConfig connectionConfig,
+            final ConnectionReuseStrategy connectionReuseStrategy) {
+        this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
+        this.exchangeHandlerFactory = Args.notNull(exchangeHandlerFactory, "Exchange handler factory");
+        this.h1Config = h1Config != null ? h1Config : H1Config.DEFAULT;
+        this.connectionConfig = connectionConfig != null ? connectionConfig: ConnectionConfig.DEFAULT;
+        this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
+                DefaultConnectionReuseStrategy.INSTANCE;
+    }
+
+    protected ServerHttp1StreamDuplexer createServerHttp1StreamDuplexer(
+            final IOSession ioSession,
+            final HttpProcessor httpProcessor,
+            final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory,
+            final H1Config h1Config,
+            final ConnectionConfig connectionConfig,
+            final ConnectionReuseStrategy connectionReuseStrategy,
+            final NHttpMessageParser<HttpRequest> incomingMessageParser,
+            final NHttpMessageWriter<HttpResponse> outgoingMessageWriter,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final ConnectionListener connectionListener,
+            final Http1StreamListener streamListener) {
+        return new ServerHttp1StreamDuplexer(ioSession, httpProcessor, exchangeHandlerFactory, h1Config,
+                connectionConfig, connectionReuseStrategy, incomingMessageParser, outgoingMessageWriter,
+                incomingContentStrategy, outgoingContentStrategy, connectionListener, streamListener);
+    }
+
+    @Override
+    public IOEventHandler createHandler(final IOSession ioSession) {
+        final String id = "http1-incoming-" + COUNT.incrementAndGet();
+        final Log sessionLog = LogFactory.getLog(ioSession.getClass());
+        final Log wireLog = LogFactory.getLog("org.apache.hc.core5.http.wire");
+        final Log headerLog = LogFactory.getLog("org.apache.hc.core5.http.headers");
+
+        final ServerHttp1StreamDuplexer streamDuplexer = createServerHttp1StreamDuplexer(
+                new LoggingIOSession(ioSession, id, sessionLog, wireLog),
+                httpProcessor,
+                exchangeHandlerFactory,
+                h1Config,
+                connectionConfig,
+                connectionReuseStrategy,
+                DefaultHttpRequestParserFactory.INSTANCE.create(h1Config),
+                DefaultHttpResponseWriterFactory.INSTANCE.create(),
+                DefaultContentLengthStrategy.INSTANCE,
+                DefaultContentLengthStrategy.INSTANCE,
+                new ConnectionListener() {
+
+                    @Override
+                    public void onConnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " connected");
+                        }
+                    }
+
+                    @Override
+                    public void onDisconnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " disconnected");
+                        }
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection connection, final Exception ex) {
+                        if (ex instanceof ConnectionClosedException) {
+                            return;
+                        }
+                        sessionLog.error(id + ": "  + ex.getMessage(), ex);
+                    }
+
+                },
+                new Http1StreamListener() {
+
+                    @Override
+                    public void onRequestHead(final HttpConnection connection, final HttpRequest request) {
+                        if (headerLog.isDebugEnabled()) {
+                            headerLog.debug(id + " << " + new RequestLine(request.getMethod(), request.getPath(),
+                                    request.getVersion() != null ? request.getVersion() : HttpVersion.HTTP_1_1));
+                            for (final Iterator<Header> it = request.headerIterator(); it.hasNext(); ) {
+                                headerLog.debug(id + " << " + it.next());
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onResponseHead(final HttpConnection connection, final HttpResponse response) {
+                        if (headerLog.isDebugEnabled()) {
+                            headerLog.debug(id + " >> " + new StatusLine(
+                                    response.getVersion() != null ? response.getVersion() : HttpVersion.HTTP_1_1,
+                                    response.getCode(), response.getReasonPhrase()));
+                            for (final Iterator<Header> it = response.headerIterator(); it.hasNext(); ) {
+                                headerLog.debug(id + " >> " + it.next());
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onExchangeComplete(final HttpConnection connection, final boolean keepAlive) {
+                        if (sessionLog.isDebugEnabled()) {
+                            if (keepAlive) {
+                                sessionLog.debug(id + " Connection is kept alive");
+                            } else {
+                                sessionLog.debug(id + " Connection is not kept alive");
+                            }
+                        }
+                    }
+
+                });
+
+        return new LoggingIOEventHandler(new ServerHttp1IOEventHandler(streamDuplexer), id, sessionLog);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http/InternalServerHttp1EventHandlerFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestClient.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestClient.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestClient.java Mon Oct 31 17:33:27 2016
@@ -28,49 +28,83 @@
 package org.apache.hc.core5.testing.nio.http2;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
+import java.nio.channels.SelectionKey;
 import java.nio.charset.StandardCharsets;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hc.core5.concurrent.BasicFuture;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ExceptionListener;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http2.bootstrap.nio.AsyncRequester;
-import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.http.MisdirectedRequestException;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncRequester;
+import org.apache.hc.core5.http.impl.nio.bootstrap.ClientEndpoint;
+import org.apache.hc.core5.http.impl.nio.bootstrap.ClientEndpointImpl;
+import org.apache.hc.core5.http.nio.AsyncPushConsumer;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.nio.Supplier;
+import org.apache.hc.core5.http.nio.command.ShutdownCommand;
+import org.apache.hc.core5.http.nio.command.ShutdownType;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.apache.hc.core5.http.protocol.RequestExpectContinue;
-import org.apache.hc.core5.http.protocol.RequestUserAgent;
 import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.http2.H2ConnectionException;
-import org.apache.hc.core5.http2.H2Error;
+import org.apache.hc.core5.http2.bootstrap.Http2Processors;
 import org.apache.hc.core5.http2.config.H2Config;
-import org.apache.hc.core5.http2.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http2.nio.HandlerFactory;
-import org.apache.hc.core5.http2.nio.Supplier;
-import org.apache.hc.core5.http2.protocol.H2RequestConnControl;
-import org.apache.hc.core5.http2.protocol.H2RequestContent;
-import org.apache.hc.core5.http2.protocol.H2RequestTargetHost;
+import org.apache.hc.core5.reactor.IOEventHandlerFactory;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.reactor.IOSessionCallback;
+import org.apache.hc.core5.reactor.SessionRequest;
+import org.apache.hc.core5.reactor.SessionRequestCallback;
 import org.apache.hc.core5.util.Args;
 
 public class Http2TestClient extends AsyncRequester {
 
     private final UriPatternMatcher<Supplier<AsyncPushConsumer>> pushHandlerMatcher;
 
-    public Http2TestClient() throws IOException {
-        super(new InternalHttpErrorListener(LogFactory.getLog(Http2TestClient.class)));
+    public Http2TestClient(final IOReactorConfig ioReactorConfig) throws IOException {
+        super(ioReactorConfig, new ExceptionListener() {
+
+            private final Log log = LogFactory.getLog(Http2TestClient.class);
+
+            @Override
+            public void onError(final Exception ex) {
+                log.error(ex.getMessage(), ex);
+            }
+
+        }, new IOSessionCallback() {
+
+            @Override
+            public void execute(final IOSession session) throws IOException {
+                session.getCommandQueue().addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
+                session.setEvent(SelectionKey.OP_WRITE);
+            }
+
+        });
         this.pushHandlerMatcher = new UriPatternMatcher<>();
     }
 
-    private AsyncPushConsumer createHandler(final HttpRequest request) throws HttpException, IOException {
+    public Http2TestClient() throws IOException {
+        this(IOReactorConfig.DEFAULT);
+    }
+
+    private AsyncPushConsumer createHandler(final HttpRequest request) throws HttpException {
 
         final HttpHost authority;
         try {
-            authority = HttpHost.create(request.getAuthority());
+            authority = request.getAuthority() != null ? HttpHost.create(request.getAuthority()) : null;
         } catch (IllegalArgumentException ex) {
-            throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
+            throw new ProtocolException("Invalid authority");
         }
-        if (!"localhost".equalsIgnoreCase(authority.getHostName())) {
-            throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Not authoritative");
+        if (authority != null && !"localhost".equalsIgnoreCase(authority.getHostName())) {
+            throw new MisdirectedRequestException("Not authoritative");
         }
         String path = request.getPath();
         final int i = path.indexOf("?");
@@ -85,30 +119,23 @@ public class Http2TestClient extends Asy
         }
     }
 
-    public void registerHandler(final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
+    public void register(final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
         Args.notNull(uriPattern, "URI pattern");
         Args.notNull(supplier, "Supplier");
         pushHandlerMatcher.register(uriPattern, supplier);
     }
 
-    public void start() throws Exception {
-        start(H2Config.DEFAULT);
+    public void start(final IOEventHandlerFactory handlerFactory) throws IOException {
+        super.execute(handlerFactory);
     }
 
-    public void start(final H2Config h2Config) throws IOException {
-        final HttpProcessor httpProcessor = new DefaultHttpProcessor(
-                new H2RequestContent(),
-                new H2RequestTargetHost(),
-                new H2RequestConnControl(),
-                new RequestUserAgent("TEST-CLIENT/1.1"),
-                new RequestExpectContinue());
+    public void start(final HttpProcessor httpProcessor, final H2Config h2Config) throws IOException {
         start(new InternalClientHttp2EventHandlerFactory(
                 httpProcessor,
                 new HandlerFactory<AsyncPushConsumer>() {
 
                     @Override
-                    public AsyncPushConsumer create(
-                            final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+                    public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
                         return createHandler(request);
                     }
 
@@ -117,4 +144,59 @@ public class Http2TestClient extends Asy
                 h2Config));
     }
 
+    public void start(final H2Config h2Config) throws IOException {
+        start(Http2Processors.client(), h2Config);
+    }
+
+    public void start() throws Exception {
+        start(H2Config.DEFAULT);
+    }
+
+    public Future<ClientEndpoint> connect(
+            final InetSocketAddress address,
+            final long timeout,
+            final TimeUnit timeUnit,
+            final FutureCallback<ClientEndpoint> callback) throws InterruptedException {
+        final BasicFuture<ClientEndpoint> future = new BasicFuture<>(callback);
+        requestSession(address, timeout, timeUnit, new SessionRequestCallback() {
+
+            @Override
+            public void completed(final SessionRequest request) {
+                final IOSession session = request.getSession();
+                future.completed(new ClientEndpointImpl(session));
+            }
+
+            @Override
+            public void failed(final SessionRequest request) {
+                future.failed(request.getException());
+            }
+
+            @Override
+            public void timeout(final SessionRequest request) {
+                future.failed(new SocketTimeoutException("Connect timeout"));
+            }
+
+            @Override
+            public void cancelled(final SessionRequest request) {
+                future.cancel();
+            }
+        });
+        return future;
+    }
+
+    public Future<ClientEndpoint> connect(
+            final InetSocketAddress address,
+            final long timeout,
+            final TimeUnit timeUnit) throws InterruptedException {
+        return connect(address, timeout, timeUnit, null);
+    }
+
+    public Future<ClientEndpoint> connect(
+            final String hostname,
+            final int port,
+            final long timeout,
+            final TimeUnit timeUnit) throws InterruptedException {
+        return connect(new InetSocketAddress(hostname, port), timeout, timeUnit);
+    }
+
 }

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestServer.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestServer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/Http2TestServer.java Mon Oct 31 17:33:27 2016
@@ -29,98 +29,90 @@ package org.apache.hc.core5.testing.nio.
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.nio.channels.SelectionKey;
 import java.nio.charset.StandardCharsets;
 
+import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpRequestInterceptor;
-import org.apache.hc.core5.http.HttpResponseInterceptor;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http2.bootstrap.nio.AsyncServer;
-import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncServer;
+import org.apache.hc.core5.http.impl.nio.bootstrap.AsyncServerExchangeHandlerRegistry;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.Supplier;
+import org.apache.hc.core5.http.nio.command.ShutdownCommand;
+import org.apache.hc.core5.http.nio.command.ShutdownType;
+import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.RequestConsumerSupplier;
+import org.apache.hc.core5.http.nio.support.ResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.apache.hc.core5.http.protocol.ResponseDate;
-import org.apache.hc.core5.http.protocol.ResponseServer;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
+import org.apache.hc.core5.http2.bootstrap.Http2Processors;
 import org.apache.hc.core5.http2.config.H2Config;
-import org.apache.hc.core5.http2.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http2.nio.FixedResponseExchangeHandler;
-import org.apache.hc.core5.http2.nio.HandlerFactory;
-import org.apache.hc.core5.http2.nio.Supplier;
-import org.apache.hc.core5.http2.protocol.H2RequestValidateHost;
-import org.apache.hc.core5.http2.protocol.H2ResponseConnControl;
-import org.apache.hc.core5.http2.protocol.H2ResponseContent;
+import org.apache.hc.core5.reactor.IOEventHandlerFactory;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.reactor.IOSessionCallback;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
-import org.apache.hc.core5.util.Args;
 
 public class Http2TestServer extends AsyncServer {
 
-    private final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> responseHandlerMatcher;
+    private final AsyncServerExchangeHandlerRegistry handlerRegistry;
+
+    public Http2TestServer(final IOReactorConfig ioReactorConfig) throws IOException {
+        super(ioReactorConfig, new ExceptionListener() {
+
+            private final Log log = LogFactory.getLog(Http2TestServer.class);
+
+            @Override
+            public void onError(final Exception ex) {
+                log.error(ex.getMessage(), ex);
+            }
+
+        }, new IOSessionCallback() {
+
+            @Override
+            public void execute(final IOSession session) throws IOException {
+                session.getCommandQueue().addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
+                session.setEvent(SelectionKey.OP_WRITE);
+            }
+
+        });
+        this.handlerRegistry = new AsyncServerExchangeHandlerRegistry("localhost");
+    }
 
     public Http2TestServer() throws IOException {
-        super(new InternalHttpErrorListener(LogFactory.getLog(Http2TestClient.class)));
-        this.responseHandlerMatcher = new UriPatternMatcher<>();
+        this(IOReactorConfig.DEFAULT);
     }
 
     public InetSocketAddress start() throws Exception {
         return start(H2Config.DEFAULT);
     }
 
-    private AsyncServerExchangeHandler createHandler(final HttpRequest request) throws HttpException {
+    public void register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
+        handlerRegistry.register(null, uriPattern, supplier);
+    }
+
+    public <T> void register(
+            final String uriPattern,
+            final RequestConsumerSupplier<T> consumerSupplier,
+            final ResponseHandler<T> responseHandler) {
+        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+            }
 
-        final HttpHost authority;
-        try {
-            authority = HttpHost.create(request.getAuthority());
-        } catch (IllegalArgumentException ex) {
-            return new FixedResponseExchangeHandler(HttpStatus.SC_BAD_REQUEST, "Invalid authority");
-        }
-        if (!"localhost".equalsIgnoreCase(authority.getHostName())) {
-            return new FixedResponseExchangeHandler(HttpStatus.SC_MISDIRECTED_REQUEST, "Not authoritative");
-        }
-        String path = request.getPath();
-        final int i = path.indexOf("?");
-        if (i != -1) {
-            path = path.substring(0, i - 1);
-        }
-        final Supplier<AsyncServerExchangeHandler> supplier = responseHandlerMatcher.lookup(path);
-        if (supplier != null) {
-            return supplier.get();
-        }
-        return new FixedResponseExchangeHandler(HttpStatus.SC_NOT_FOUND, "Resource not found");
-    }
-
-    public void registerHandler(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
-        Args.notNull(uriPattern, "URI pattern");
-        Args.notNull(supplier, "Supplier");
-        responseHandlerMatcher.register(uriPattern, supplier);
+        });
     }
 
-    public InetSocketAddress start(final H2Config h2Config) throws Exception {
-        final HttpProcessor httpProcessor = new DefaultHttpProcessor(
-                new HttpRequestInterceptor[] {
-                        new H2RequestValidateHost()
-                },
-                new HttpResponseInterceptor[]{
-                        new ResponseDate(),
-                        new ResponseServer("TEST-SERVER/1.1"),
-                        new H2ResponseContent(),
-                        new H2ResponseConnControl()
-                });
+    public void start(final IOEventHandlerFactory handlerFactory) throws IOException {
+        execute(handlerFactory);
+    }
+
+    public InetSocketAddress start(final HttpProcessor httpProcessor, final H2Config h2Config) throws Exception {
         start(new InternalServerHttp2EventHandlerFactory(
                 httpProcessor,
-                new HandlerFactory<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler create(
-                            final HttpRequest request,
-                            final HttpContext context) throws HttpException {
-                        return createHandler(request);
-                    }
-
-                },
+                handlerRegistry,
                 StandardCharsets.US_ASCII,
                 h2Config));
         final ListenerEndpoint listener = listen(new InetSocketAddress(0));
@@ -128,4 +120,8 @@ public class Http2TestServer extends Asy
         return (InetSocketAddress) listener.getAddress();
     }
 
+    public InetSocketAddress start(final H2Config h2Config) throws Exception {
+        return start(Http2Processors.server(), h2Config);
+    }
+
 }

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalClientHttp2EventHandlerFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalClientHttp2EventHandlerFactory.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalClientHttp2EventHandlerFactory.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalClientHttp2EventHandlerFactory.java Mon Oct 31 17:33:27 2016
@@ -32,19 +32,23 @@ import java.util.concurrent.atomic.Atomi
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.HttpConnection;
+import org.apache.hc.core5.http.impl.nio.ConnectionListener;
+import org.apache.hc.core5.http.nio.AsyncPushConsumer;
+import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexer;
 import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiator;
-import org.apache.hc.core5.http2.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http2.nio.HandlerFactory;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.testing.nio.LoggingIOEventHandler;
+import org.apache.hc.core5.testing.nio.LoggingIOSession;
 import org.apache.hc.core5.util.Args;
 
-public class InternalClientHttp2EventHandlerFactory implements IOEventHandlerFactory {
+class InternalClientHttp2EventHandlerFactory implements IOEventHandlerFactory {
 
     private static final AtomicLong COUNT = new AtomicLong();
 
@@ -53,7 +57,7 @@ public class InternalClientHttp2EventHan
     private final Charset charset;
     private final H2Config h2Config;
 
-    public InternalClientHttp2EventHandlerFactory(
+    InternalClientHttp2EventHandlerFactory(
             final HttpProcessor httpProcessor,
             final HandlerFactory<AsyncPushConsumer> exchangeHandlerFactory,
             final Charset charset,
@@ -68,15 +72,39 @@ public class InternalClientHttp2EventHan
     public IOEventHandler createHandler(final IOSession ioSession) {
         final String id = "http2-outgoing-" + COUNT.incrementAndGet();
         final Log sessionLog = LogFactory.getLog(ioSession.getClass());
-        final InternalHttp2StreamListener streamListener = new InternalHttp2StreamListener(id);
-        final ExceptionListener errorListener = new InternalHttpErrorListener(sessionLog);
-        return new ClientHttpProtocolNegotiator(httpProcessor, exchangeHandlerFactory, charset, h2Config, streamListener, errorListener) {
+        return new LoggingIOEventHandler(new ClientHttpProtocolNegotiator(
+                ioSession, httpProcessor, exchangeHandlerFactory, charset, h2Config,
+                new ConnectionListener() {
+
+                    @Override
+                    public void onConnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " connected");
+                        }
+                    }
+
+                    @Override
+                    public void onDisconnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " disconnected");
+                        }
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection connection, final Exception ex) {
+                        if (ex instanceof ConnectionClosedException) {
+                            return;
+                        }
+                        sessionLog.error(id + ": "  + ex.getMessage(), ex);
+                    }
+
+                }, new InternalHttp2StreamListener(id)) {
 
             @Override
             protected ClientHttp2StreamMultiplexer createStreamMultiplexer(final IOSession ioSession) {
                 return super.createStreamMultiplexer(new LoggingIOSession(ioSession, id, sessionLog));
             }
-        };
+        }, id, sessionLog);
 
    }
 

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalServerHttp2EventHandlerFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalServerHttp2EventHandlerFactory.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalServerHttp2EventHandlerFactory.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/http2/InternalServerHttp2EventHandlerFactory.java Mon Oct 31 17:33:27 2016
@@ -32,19 +32,23 @@ import java.util.concurrent.atomic.Atomi
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.HttpConnection;
+import org.apache.hc.core5.http.impl.nio.ConnectionListener;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.http2.impl.nio.ServerHttp2StreamMultiplexer;
 import org.apache.hc.core5.http2.impl.nio.ServerHttpProtocolNegotiator;
-import org.apache.hc.core5.http2.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http2.nio.HandlerFactory;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.testing.nio.LoggingIOEventHandler;
+import org.apache.hc.core5.testing.nio.LoggingIOSession;
 import org.apache.hc.core5.util.Args;
 
-public class InternalServerHttp2EventHandlerFactory implements IOEventHandlerFactory {
+class InternalServerHttp2EventHandlerFactory implements IOEventHandlerFactory {
 
     private static final AtomicLong COUNT = new AtomicLong();
 
@@ -68,15 +72,39 @@ public class InternalServerHttp2EventHan
     public IOEventHandler createHandler(final IOSession ioSession) {
         final String id = "http2-incoming-" + COUNT.incrementAndGet();
         final Log sessionLog = LogFactory.getLog(ioSession.getClass());
-        final InternalHttp2StreamListener streamListener = new InternalHttp2StreamListener(id);
-        final ExceptionListener errorListener = new InternalHttpErrorListener(sessionLog);
-        return new ServerHttpProtocolNegotiator(httpProcessor, exchangeHandlerFactory, charset, h2Config, streamListener, errorListener) {
+        return new LoggingIOEventHandler(new ServerHttpProtocolNegotiator(
+                ioSession, httpProcessor, exchangeHandlerFactory, charset, h2Config,
+                new ConnectionListener() {
+
+                    @Override
+                    public void onConnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " connected");
+                        }
+                    }
+
+                    @Override
+                    public void onDisconnect(final HttpConnection connection) {
+                        if (sessionLog.isDebugEnabled()) {
+                            sessionLog.debug(id + ": "  + connection + " disconnected");
+                        }
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection connection, final Exception ex) {
+                        if (ex instanceof ConnectionClosedException) {
+                            return;
+                        }
+                        sessionLog.error(id + ": "  + ex.getMessage(), ex);
+                    }
+
+                }, new InternalHttp2StreamListener(id)) {
 
             @Override
             protected ServerHttp2StreamMultiplexer createStreamMultiplexer(final IOSession ioSession) {
                 return super.createStreamMultiplexer(new LoggingIOSession(ioSession, id, sessionLog));
             }
-        };
+        }, id, sessionLog);
 
     }
 }

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java?rev=1767339&r1=1767338&r2=1767339&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java Mon Oct 31 17:33:27 2016
@@ -51,14 +51,14 @@ import org.apache.hc.core5.http.HttpRequ
 import org.apache.hc.core5.http.HttpRequestInterceptor;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.entity.AbstractHttpEntity;
-import org.apache.hc.core5.http.entity.ByteArrayEntity;
-import org.apache.hc.core5.http.entity.ContentType;
-import org.apache.hc.core5.http.entity.EntityUtils;
-import org.apache.hc.core5.http.entity.StringEntity;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection;
 import org.apache.hc.core5.http.io.HttpExpectationVerifier;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.ContentType;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpContext;