hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [3/6] httpcomponents-core git commit: Protocol handling API refactoring (no functional changes, mostly moving code to different packages)
Date Tue, 01 Aug 2017 19:07:01 GMT
Protocol handling API refactoring (no functional changes, mostly moving code to different packages)


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

Branch: refs/heads/master
Commit: 9f39bfdcbfb58246acc45a2e26ada617ecac17d8
Parents: 94721e0
Author: Oleg Kalnichevski <olegk@apache.org>
Authored: Sat Jul 22 13:40:38 2017 +0200
Committer: Oleg Kalnichevski <olegk@apache.org>
Committed: Mon Jul 31 10:05:52 2017 +0200

----------------------------------------------------------------------
 .../hc/core5/http/benchmark/HttpServer.java     | 179 -----------
 .../hc/core5/http/benchmark/SmokeTest.java      |  36 ++-
 .../http/examples/Http2FileServerExample.java   |  13 +-
 .../bootstrap/AsyncPushConsumerRegistry.java    | 103 -------
 .../nio/bootstrap/H2RequesterBootstrap.java     |   1 +
 .../impl/nio/bootstrap/H2ServerBootstrap.java   |  15 +-
 .../nio/support/AsyncPushConsumerRegistry.java  | 103 +++++++
 .../impl/nio/entity/TestSharedInputBuffer.java  |   2 +-
 .../impl/nio/entity/TestSharedOutputBuffer.java |   2 +-
 .../testing/classic/ClassicTestServer.java      |   2 +-
 .../hc/core5/testing/nio/Http1TestServer.java   |  10 +-
 .../hc/core5/testing/nio/Http2TestClient.java   |   2 +-
 .../hc/core5/testing/nio/Http2TestServer.java   |  10 +-
 .../core5/testing/nio/Http1IntegrationTest.java |  20 +-
 .../core5/testing/nio/Http2IntegrationTest.java |  18 +-
 .../testing/nio/MultiLineResponseHandler.java   |  13 +-
 .../testing/nio/SingleLineResponseHandler.java  |  13 +-
 .../http/examples/AsyncFileServerExample.java   |  13 +-
 .../impl/bootstrap/AsyncServerBootstrap.java    |  14 +-
 .../AsyncServerExchangeHandlerRegistry.java     | 108 -------
 .../http/impl/bootstrap/ServerBootstrap.java    |   2 +-
 .../AbstractClassicServerExchangeHandler.java   | 302 -------------------
 .../entity/AbstractClassicEntityConsumer.java   | 135 ---------
 .../entity/AbstractClassicEntityProducer.java   | 131 --------
 .../impl/nio/entity/AbstractSharedBuffer.java   | 119 --------
 .../http/impl/nio/entity/SharedInputBuffer.java | 164 ----------
 .../impl/nio/entity/SharedOutputBuffer.java     | 166 ----------
 .../http/io/UriHttpRequestHandlerMapper.java    | 120 --------
 .../io/support/UriHttpRequestHandlerMapper.java | 122 ++++++++
 .../http/nio/AsyncClientExchangeHandler.java    |   4 +-
 .../http/nio/AsyncDataExchangeHandler.java      |  39 +++
 .../hc/core5/http/nio/AsyncRequestProducer.java |   9 +-
 .../core5/http/nio/AsyncResponseProducer.java   |   9 +-
 .../http/nio/AsyncServerExchangeHandler.java    |   4 +-
 .../http/nio/AsyncServerRequestHandler.java     |  47 +++
 .../http/nio/AsyncServerResponseTrigger.java    |  49 +++
 .../hc/core5/http/nio/BasicRequestProducer.java |  11 +-
 .../core5/http/nio/BasicResponseProducer.java   |  13 +-
 .../entity/AbstractClassicEntityConsumer.java   | 134 ++++++++
 .../entity/AbstractClassicEntityProducer.java   | 130 ++++++++
 .../http/nio/entity/AbstractSharedBuffer.java   | 119 ++++++++
 .../http/nio/entity/SharedInputBuffer.java      | 163 ++++++++++
 .../http/nio/entity/SharedOutputBuffer.java     | 165 ++++++++++
 .../AbstractClassicServerExchangeHandler.java   | 302 +++++++++++++++++++
 .../support/AbstractServerExchangeHandler.java  |  17 +-
 .../AsyncServerExchangeHandlerRegistry.java     | 107 +++++++
 .../nio/support/BasicAsyncRequestProducer.java  |  83 -----
 .../nio/support/BasicAsyncResponseProducer.java |  83 -----
 .../nio/support/BasicClientExchangeHandler.java |   5 +-
 .../nio/support/BasicServerExchangeHandler.java |  18 +-
 .../ImmediateResponseExchangeHandler.java       |   2 +-
 .../nio/support/RequestConsumerSupplier.java    |  44 ---
 .../core5/http/nio/support/ResponseHandler.java |  44 ---
 .../core5/http/nio/support/ResponseTrigger.java |  51 ----
 .../TestAsyncServerExchangeHandlerRegistry.java |  73 -----
 .../io/TestUriHttpRequestHandlerMapper.java     | 107 -------
 .../TestUriHttpRequestHandlerMapper.java        | 108 +++++++
 .../TestAsyncServerExchangeHandlerRegistry.java |  72 +++++
 58 files changed, 1784 insertions(+), 2166 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/HttpServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/HttpServer.java b/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/HttpServer.java
deleted file mode 100644
index 16b37df..0000000
--- a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/HttpServer.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * ====================================================================
- * 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.http.benchmark;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import org.apache.hc.core5.http.ConnectionClosedException;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.config.H1Config;
-import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
-import org.apache.hc.core5.http.impl.io.DefaultClassicHttpResponseFactory;
-import org.apache.hc.core5.http.impl.io.HttpService;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpServerConnection;
-import org.apache.hc.core5.http.io.UriHttpRequestHandlerMapper;
-import org.apache.hc.core5.http.protocol.BasicHttpContext;
-import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.apache.hc.core5.http.protocol.ResponseConnControl;
-import org.apache.hc.core5.http.protocol.ResponseContent;
-import org.apache.hc.core5.http.protocol.ResponseDate;
-import org.apache.hc.core5.http.protocol.ResponseServer;
-import org.apache.hc.core5.io.ShutdownType;
-import org.apache.hc.core5.util.Asserts;
-
-public class HttpServer {
-
-    private final HttpProcessor httpproc;
-    private final UriHttpRequestHandlerMapper reqistry;
-    private final ServerSocket serversocket;
-
-    private Thread listener;
-    private volatile boolean shutdown;
-
-    public HttpServer() throws IOException {
-        super();
-        this.httpproc = new DefaultHttpProcessor(
-                new ResponseDate(),
-                new ResponseServer("TEST-SERVER/1.1"),
-                new ResponseContent(),
-                new ResponseConnControl());
-        this.reqistry = new UriHttpRequestHandlerMapper();
-        this.serversocket = new ServerSocket(0);
-    }
-
-    public void registerHandler(
-            final String pattern,
-            final HttpRequestHandler handler) {
-        this.reqistry.register(pattern, handler);
-    }
-
-    private HttpServerConnection acceptConnection() throws IOException {
-        final Socket socket = this.serversocket.accept();
-        final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(null, H1Config.DEFAULT);
-        conn.bind(socket);
-        return conn;
-    }
-
-    public int getPort() {
-        return this.serversocket.getLocalPort();
-    }
-
-    public InetAddress getInetAddress() {
-        return this.serversocket.getInetAddress();
-    }
-
-    public void start() {
-        Asserts.check(this.listener == null, "Listener already running");
-        this.listener = new Thread(new Runnable() {
-
-            @Override
-            public void run() {
-                while (!shutdown && !Thread.interrupted()) {
-                    try {
-                        // Set up HTTP connection
-                        final HttpServerConnection conn = acceptConnection();
-                        // Set up the HTTP service
-                        final HttpService httpService = new HttpService(
-                                httpproc,
-                                DefaultConnectionReuseStrategy.INSTANCE,
-                                DefaultClassicHttpResponseFactory.INSTANCE,
-                                reqistry,
-                                null,
-                                null);
-                        // Start worker thread
-                        final Thread t = new WorkerThread(httpService, conn);
-                        t.setDaemon(true);
-                        t.start();
-                    } catch (final InterruptedIOException ex) {
-                        break;
-                    } catch (final IOException e) {
-                        break;
-                    }
-                }
-            }
-
-        });
-        this.listener.start();
-    }
-
-    public void shutdown() {
-        if (this.shutdown) {
-            return;
-        }
-        this.shutdown = true;
-        try {
-            this.serversocket.close();
-        } catch (final IOException ignore) {}
-        this.listener.interrupt();
-        try {
-            this.listener.join(1000);
-        } catch (final InterruptedException ignore) {}
-    }
-
-    static class WorkerThread extends Thread {
-
-        private final HttpService httpservice;
-        private final HttpServerConnection conn;
-
-        public WorkerThread(
-                final HttpService httpservice,
-                final HttpServerConnection conn) {
-            super();
-            this.httpservice = httpservice;
-            this.conn = conn;
-        }
-
-        @Override
-        public void run() {
-            final HttpContext context = new BasicHttpContext(null);
-            try {
-                while (!Thread.interrupted() && this.conn.isOpen()) {
-                    this.httpservice.handleRequest(this.conn, context);
-                }
-                this.conn.shutdown(ShutdownType.GRACEFUL);
-            } catch (final ConnectionClosedException ex) {
-            } catch (final IOException ex) {
-                System.err.println("I/O error: " + ex.getMessage());
-            } catch (final HttpException ex) {
-                System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
-            } finally {
-                this.conn.shutdown(ShutdownType.IMMEDIATE);
-            }
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java b/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
index b02db38..28b3559 100644
--- a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
+++ b/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
@@ -29,14 +29,17 @@ package org.apache.hc.core5.http.benchmark;
 import java.io.IOException;
 import java.net.URL;
 
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.io.ShutdownType;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -48,23 +51,24 @@ public class SmokeTest {
 
     @Before
     public void setup() throws Exception {
-        server = new HttpServer();
-        server.registerHandler("/", new HttpRequestHandler() {
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_OK);
-                response.setEntity(new StringEntity("0123456789ABCDEF", ContentType.TEXT_PLAIN));
-            }
-        });
+        server = ServerBootstrap.bootstrap()
+                .registerHandler("/", new HttpRequestHandler() {
+                    @Override
+                    public void handle(
+                            final ClassicHttpRequest request,
+                            final ClassicHttpResponse response,
+                            final HttpContext context) throws HttpException, IOException {
+                        response.setCode(HttpStatus.SC_OK);
+                        response.setEntity(new StringEntity("0123456789ABCDEF", ContentType.TEXT_PLAIN));
+                    }
+                })
+                .create();
         server.start();
     }
 
     @After
     public void shutdown() throws Exception {
-        server.shutdown();
+        server.shutdown(ShutdownType.IMMEDIATE);
     }
 
     @Test
@@ -72,7 +76,7 @@ public class SmokeTest {
         final Config config = new Config();
         config.setKeepAlive(true);
         config.setMethod("GET");
-        config.setUrl(new URL("http://localhost:" + server.getPort() + "/"));
+        config.setUrl(new URL("http://localhost:" + server.getLocalPort() + "/"));
         config.setThreads(3);
         config.setRequests(100);
         final HttpBenchmark httpBenchmark = new HttpBenchmark(config);

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/examples/org/apache/hc/core5/http/examples/Http2FileServerExample.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/examples/org/apache/hc/core5/http/examples/Http2FileServerExample.java b/httpcore5-h2/src/examples/org/apache/hc/core5/http/examples/Http2FileServerExample.java
index ba0b096..29ed426 100644
--- a/httpcore5-h2/src/examples/org/apache/hc/core5/http/examples/Http2FileServerExample.java
+++ b/httpcore5-h2/src/examples/org/apache/hc/core5/http/examples/Http2FileServerExample.java
@@ -47,13 +47,12 @@ import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.entity.FileEntityProducer;
 import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
-import org.apache.hc.core5.http.nio.support.RequestConsumerSupplier;
-import org.apache.hc.core5.http.nio.support.ResponseHandler;
-import org.apache.hc.core5.http.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.http2.frame.RawFrame;
@@ -121,21 +120,19 @@ public class Http2FileServerExample {
                     }
 
                 })
-                .register("*", new RequestConsumerSupplier<Message<HttpRequest, Void>>() {
+                .register("*", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
 
                     @Override
-                    public AsyncRequestConsumer<Message<HttpRequest, Void>> get(
+                    public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(
                             final HttpRequest request,
                             final HttpContext context) throws HttpException {
                         return new BasicRequestConsumer<>(new NoopEntityConsumer());
                     }
 
-                }, new ResponseHandler<Message<HttpRequest, Void>>() {
-
                     @Override
                     public void handle(
                             final Message<HttpRequest, Void> message,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws HttpException, IOException {
                         HttpRequest request = message.getHead();
                         URI requestUri;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/AsyncPushConsumerRegistry.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/AsyncPushConsumerRegistry.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/AsyncPushConsumerRegistry.java
deleted file mode 100644
index e33c392..0000000
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/AsyncPushConsumerRegistry.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ====================================================================
- * 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.http2.impl.nio.bootstrap;
-
-import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.net.URIAuthority;
-import org.apache.hc.core5.util.Args;
-
-public class AsyncPushConsumerRegistry implements HandlerFactory<AsyncPushConsumer> {
-
-    private final UriPatternMatcher<Supplier<AsyncPushConsumer>> primary;
-    private final ConcurrentMap<String, UriPatternMatcher<Supplier<AsyncPushConsumer>>> hostMap;
-
-    public AsyncPushConsumerRegistry() {
-        this.primary = new UriPatternMatcher<>();
-        this.hostMap = new ConcurrentHashMap<>();
-    }
-
-    private UriPatternMatcher<Supplier<AsyncPushConsumer>> getPatternMatcher(final String hostname) {
-        if (hostname == null) {
-            return primary;
-        }
-        final UriPatternMatcher<Supplier<AsyncPushConsumer>> hostMatcher = hostMap.get(hostname);
-        if (hostMatcher != null) {
-            return hostMatcher;
-        }
-        return primary;
-    }
-
-    @Override
-    public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
-        final URIAuthority authority = request.getAuthority();
-        final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
-        final UriPatternMatcher<Supplier<AsyncPushConsumer>> patternMatcher = getPatternMatcher(key);
-        if (patternMatcher == null) {
-            return null;
-        }
-        String path = request.getPath();
-        final int i = path.indexOf("?");
-        if (i != -1) {
-            path = path.substring(0, i - 1);
-        }
-        final Supplier<AsyncPushConsumer> supplier = patternMatcher.lookup(path);
-        if (supplier != null) {
-            return supplier.get();
-        }
-        return null;
-    }
-
-    public void register(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
-        Args.notBlank(uriPattern, "URI pattern");
-        Args.notNull(supplier, "Supplier");
-        if (hostname == null) {
-            primary.register(uriPattern, supplier);
-        } else {
-            final String key = hostname.toLowerCase(Locale.ROOT);
-            UriPatternMatcher<Supplier<AsyncPushConsumer>> matcher = hostMap.get(key);
-            if (matcher == null) {
-                final UriPatternMatcher<Supplier<AsyncPushConsumer>> newMatcher = new UriPatternMatcher<>();
-                matcher = hostMap.putIfAbsent(key, newMatcher);
-                if (matcher == null) {
-                    matcher = newMatcher;
-                }
-            }
-            matcher.register(uriPattern, supplier);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index d09633f..4d1043f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -46,6 +46,7 @@ import org.apache.hc.core5.http2.impl.Http2Processors;
 import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
 import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiatorFactory;
 import org.apache.hc.core5.http2.impl.nio.Http2StreamListener;
+import org.apache.hc.core5.http2.nio.support.AsyncPushConsumerRegistry;
 import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
 import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.ConnPoolPolicy;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index 9b2a921..288bb2a 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -37,16 +37,15 @@ import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
 import org.apache.hc.core5.http.impl.Http1StreamListener;
 import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.impl.bootstrap.AsyncServerExchangeHandlerRegistry;
+import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 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.ServerHttp1StreamDuplexerFactory;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 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.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
@@ -204,13 +203,12 @@ public class H2ServerBootstrap {
 
     public final <T> H2ServerBootstrap register(
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });
@@ -220,13 +218,12 @@ public class H2ServerBootstrap {
     public final <T> H2ServerBootstrap registerVirtual(
             final String hostname,
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         registerVirtual(hostname, uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
new file mode 100644
index 0000000..b44ccf4
--- /dev/null
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
@@ -0,0 +1,103 @@
+/*
+ * ====================================================================
+ * 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.http2.nio.support;
+
+import java.util.Locale;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.nio.AsyncPushConsumer;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.protocol.UriPatternMatcher;
+import org.apache.hc.core5.net.URIAuthority;
+import org.apache.hc.core5.util.Args;
+
+public class AsyncPushConsumerRegistry implements HandlerFactory<AsyncPushConsumer> {
+
+    private final UriPatternMatcher<Supplier<AsyncPushConsumer>> primary;
+    private final ConcurrentMap<String, UriPatternMatcher<Supplier<AsyncPushConsumer>>> hostMap;
+
+    public AsyncPushConsumerRegistry() {
+        this.primary = new UriPatternMatcher<>();
+        this.hostMap = new ConcurrentHashMap<>();
+    }
+
+    private UriPatternMatcher<Supplier<AsyncPushConsumer>> getPatternMatcher(final String hostname) {
+        if (hostname == null) {
+            return primary;
+        }
+        final UriPatternMatcher<Supplier<AsyncPushConsumer>> hostMatcher = hostMap.get(hostname);
+        if (hostMatcher != null) {
+            return hostMatcher;
+        }
+        return primary;
+    }
+
+    @Override
+    public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
+        final URIAuthority authority = request.getAuthority();
+        final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
+        final UriPatternMatcher<Supplier<AsyncPushConsumer>> patternMatcher = getPatternMatcher(key);
+        if (patternMatcher == null) {
+            return null;
+        }
+        String path = request.getPath();
+        final int i = path.indexOf("?");
+        if (i != -1) {
+            path = path.substring(0, i - 1);
+        }
+        final Supplier<AsyncPushConsumer> supplier = patternMatcher.lookup(path);
+        if (supplier != null) {
+            return supplier.get();
+        }
+        return null;
+    }
+
+    public void register(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
+        Args.notBlank(uriPattern, "URI pattern");
+        Args.notNull(supplier, "Supplier");
+        if (hostname == null) {
+            primary.register(uriPattern, supplier);
+        } else {
+            final String key = hostname.toLowerCase(Locale.ROOT);
+            UriPatternMatcher<Supplier<AsyncPushConsumer>> matcher = hostMap.get(key);
+            if (matcher == null) {
+                final UriPatternMatcher<Supplier<AsyncPushConsumer>> newMatcher = new UriPatternMatcher<>();
+                matcher = hostMap.putIfAbsent(key, newMatcher);
+                if (matcher == null) {
+                    matcher = newMatcher;
+                }
+            }
+            matcher.register(uriPattern, supplier);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedInputBuffer.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedInputBuffer.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedInputBuffer.java
index 60de1f3..158efdb 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedInputBuffer.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedInputBuffer.java
@@ -37,7 +37,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.core5.http.impl.nio.entity.SharedInputBuffer;
+import org.apache.hc.core5.http.nio.entity.SharedInputBuffer;
 import org.apache.hc.core5.http.nio.CapacityChannel;
 import org.junit.Assert;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedOutputBuffer.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedOutputBuffer.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedOutputBuffer.java
index 6047e1f..86af685 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedOutputBuffer.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/entity/TestSharedOutputBuffer.java
@@ -41,7 +41,7 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.impl.nio.entity.SharedOutputBuffer;
+import org.apache.hc.core5.http.nio.entity.SharedOutputBuffer;
 import org.apache.hc.core5.http.nio.DataStreamChannel;
 import org.apache.hc.core5.http2.WritableByteChannelMock;
 import org.junit.Assert;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
index 1afa6e6..ac9026e 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
@@ -38,7 +38,7 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.HttpExpectationVerifier;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.UriHttpRequestHandlerMapper;
+import org.apache.hc.core5.http.io.support.UriHttpRequestHandlerMapper;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.io.ShutdownType;
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
index b2a034a..9960d6e 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
@@ -38,11 +38,10 @@ import org.apache.hc.core5.http.config.CharCodingConfig;
 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.bootstrap.AsyncServerExchangeHandlerRegistry;
+import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 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;
@@ -69,13 +68,12 @@ public class Http1TestServer extends AsyncServer {
 
     public <T> void register(
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
index 8246a21..1f2f2eb 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
@@ -43,7 +43,7 @@ import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.http2.impl.Http2Processors;
-import org.apache.hc.core5.http2.impl.nio.bootstrap.AsyncPushConsumerRegistry;
+import org.apache.hc.core5.http2.nio.support.AsyncPushConsumerRegistry;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.IOSession;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
index 31b8990..7f7cb3f 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
@@ -37,11 +37,10 @@ import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.impl.bootstrap.AsyncServerExchangeHandlerRegistry;
+import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 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.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
@@ -71,13 +70,12 @@ public class Http2TestServer extends AsyncServer {
 
     public <T> void register(
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 66fab77..0bc01f2 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -82,11 +82,8 @@ import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.hc.core5.http.impl.Http1StreamListener;
 import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.impl.nio.AbstractClassicServerExchangeHandler;
 import org.apache.hc.core5.http.impl.nio.AbstractContentEncoder;
 import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer;
-import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityConsumer;
-import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityProducer;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
@@ -94,6 +91,7 @@ import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncRequestProducer;
 import org.apache.hc.core5.http.nio.AsyncResponseProducer;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.BasicResponseConsumer;
@@ -106,13 +104,15 @@ import org.apache.hc.core5.http.nio.NHttpMessageParser;
 import org.apache.hc.core5.http.nio.NHttpMessageWriter;
 import org.apache.hc.core5.http.nio.ResponseChannel;
 import org.apache.hc.core5.http.nio.SessionOutputBuffer;
+import org.apache.hc.core5.http.nio.entity.AbstractClassicEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.AbstractClassicEntityProducer;
 import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.support.AbstractClassicServerExchangeHandler;
 import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
-import org.apache.hc.core5.http.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -711,7 +711,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, String> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
                         responseTrigger.submitResponse(
                                 new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
@@ -915,7 +915,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                             producer = new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
                         }
                         responseProducer.set(producer);
-                        responseChannel.sendResponse(producer.produceResponse(), producer.getEntityDetails());
+                        producer.sendResponse(responseChannel);
                     }
 
                     @Override
@@ -1354,7 +1354,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                             @Override
                             protected void handle(
                                     final Message<HttpRequest, String> request,
-                                    final ResponseTrigger responseTrigger,
+                                    final AsyncServerResponseTrigger responseTrigger,
                                     final HttpContext context) throws IOException, HttpException {
                                 responseTrigger.submitResponse(
                                         new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")));
@@ -1438,7 +1438,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, String> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
                         throw new HttpException("Boom");
                     }
@@ -1497,7 +1497,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, String> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
                         final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT);
                         responseTrigger.submitResponse(new BasicResponseProducer(response));
@@ -1584,7 +1584,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, String> requestMessage,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws HttpException, IOException {
                         responseTrigger.submitResponse(new BasicResponseProducer(
                                 HttpStatus.SC_OK,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
index 22f8c72..3b105c0 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
@@ -77,14 +77,12 @@ import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.URIScheme;
-import org.apache.hc.core5.http.impl.nio.AbstractClassicServerExchangeHandler;
-import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityConsumer;
-import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityProducer;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncResponseProducer;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicPushProducer;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicRequestProducer;
@@ -93,6 +91,8 @@ import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.CapacityChannel;
 import org.apache.hc.core5.http.nio.DataStreamChannel;
 import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.nio.entity.AbstractClassicEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.AbstractClassicEntityProducer;
 import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
@@ -100,8 +100,8 @@ import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.AbstractAsyncPushHandler;
+import org.apache.hc.core5.http.nio.support.AbstractClassicServerExchangeHandler;
 import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
-import org.apache.hc.core5.http.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http2.H2Error;
 import org.apache.hc.core5.http2.H2StreamResetException;
@@ -576,7 +576,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, Void> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
                         responseTrigger.pushPromise(
                                 new BasicHttpRequest("GET", createRequestURI(serverEndpoint, "/stuff")),
@@ -656,7 +656,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, Void> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
 
                         responseTrigger.pushPromise(
@@ -777,7 +777,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, Void> request,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws IOException, HttpException {
                         responseTrigger.submitResponse(
                                 new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
@@ -855,7 +855,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
                             producer = new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
                         }
                         responseProducer.set(producer);
-                        responseChannel.sendResponse(producer.produceResponse(), producer.getEntityDetails());
+                        producer.sendResponse(responseChannel);
                     }
 
                     @Override
@@ -917,7 +917,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
                     @Override
                     protected void handle(
                             final Message<HttpRequest, String> requestMessage,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws HttpException, IOException {
                         responseTrigger.submitResponse(new BasicResponseProducer(
                                 HttpStatus.SC_OK,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/MultiLineResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/MultiLineResponseHandler.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/MultiLineResponseHandler.java
index cdf6510..4e025d4 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/MultiLineResponseHandler.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/MultiLineResponseHandler.java
@@ -35,33 +35,30 @@ import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 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.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 public class MultiLineResponseHandler extends BasicServerExchangeHandler<Message<HttpRequest, String>> {
 
     public MultiLineResponseHandler(final String message, final int count) {
-        super(new RequestConsumerSupplier<Message<HttpRequest, String>>() {
+        super(new AsyncServerRequestHandler<Message<HttpRequest, String>>() {
 
                   @Override
-                  public AsyncRequestConsumer<Message<HttpRequest, String>> get(
+                  public AsyncRequestConsumer<Message<HttpRequest, String>> prepare(
                           final HttpRequest request,
                           final HttpContext context) throws HttpException {
                       return new BasicRequestConsumer<>(new StringAsyncEntityConsumer());
                   }
 
-              }, new ResponseHandler<Message<HttpRequest, String>>() {
-
                   @Override
                   public void handle(
                           final Message<HttpRequest, String> requestMessage,
-                          final ResponseTrigger responseTrigger,
+                          final AsyncServerResponseTrigger responseTrigger,
                           final HttpContext context) throws HttpException, IOException {
                       final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
                       responseTrigger.submitResponse(new BasicResponseProducer(

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
index b17e939..af8d453 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
@@ -33,34 +33,31 @@ import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 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.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 public class SingleLineResponseHandler extends BasicServerExchangeHandler<Message<HttpRequest, String>> {
 
     public SingleLineResponseHandler(final String message) {
-        super(new RequestConsumerSupplier<Message<HttpRequest, String>>() {
+        super(new AsyncServerRequestHandler<Message<HttpRequest, String>>() {
 
                   @Override
-                  public AsyncRequestConsumer<Message<HttpRequest, String>> get(
+                  public AsyncRequestConsumer<Message<HttpRequest, String>> prepare(
                           final HttpRequest request,
                           final HttpContext context) throws HttpException {
                       return new BasicRequestConsumer<>(new StringAsyncEntityConsumer());
                   }
 
-              }, new ResponseHandler<Message<HttpRequest, String>>() {
-
                   @Override
                   public void handle(
                           final Message<HttpRequest, String> requestMessage,
-                          final ResponseTrigger responseTrigger,
+                          final AsyncServerResponseTrigger responseTrigger,
                           final HttpContext context) throws HttpException, IOException {
                       responseTrigger.submitResponse(new BasicResponseProducer(
                               HttpStatus.SC_OK, new BasicAsyncEntityProducer(message)));

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncFileServerExample.java b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
index b1f5de4..ed0c077 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
@@ -45,13 +45,12 @@ import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.AsyncServerResponseTrigger;
 import org.apache.hc.core5.http.nio.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.entity.FileEntityProducer;
 import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
-import org.apache.hc.core5.http.nio.support.RequestConsumerSupplier;
-import org.apache.hc.core5.http.nio.support.ResponseHandler;
-import org.apache.hc.core5.http.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.ShutdownType;
@@ -83,21 +82,19 @@ public class AsyncFileServerExample {
 
         final HttpAsyncServer server = AsyncServerBootstrap.bootstrap()
                 .setIOReactorConfig(config)
-                .register("*", new RequestConsumerSupplier<Message<HttpRequest, Void>>() {
+                .register("*", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
 
                     @Override
-                    public AsyncRequestConsumer<Message<HttpRequest, Void>> get(
+                    public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(
                             final HttpRequest request,
                             final HttpContext context) throws HttpException {
                         return new BasicRequestConsumer<>(new NoopEntityConsumer());
                     }
 
-                }, new ResponseHandler<Message<HttpRequest, Void>>() {
-
                     @Override
                     public void handle(
                             final Message<HttpRequest, Void> message,
-                            final ResponseTrigger responseTrigger,
+                            final AsyncServerResponseTrigger responseTrigger,
                             final HttpContext context) throws HttpException, IOException {
                         HttpRequest request = message.getHead();
                         URI requestUri;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
index fa75073..18c9064 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
@@ -43,11 +43,11 @@ import org.apache.hc.core5.http.impl.nio.DefaultHttpResponseWriterFactory;
 import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandlerFactory;
 import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexerFactory;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.ssl.BasicServerTlsStrategy;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
 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.net.InetAddressUtils;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
@@ -182,13 +182,12 @@ public class AsyncServerBootstrap {
 
     public final <T> AsyncServerBootstrap register(
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });
@@ -198,13 +197,12 @@ public class AsyncServerBootstrap {
     public final <T> AsyncServerBootstrap registerVirtual(
             final String hostname,
             final String uriPattern,
-            final RequestConsumerSupplier<T> consumerSupplier,
-            final ResponseHandler<T> responseHandler) {
+            final AsyncServerRequestHandler<T> requestHandler) {
         registerVirtual(hostname, uriPattern, new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler);
+                return new BasicServerExchangeHandler<>(requestHandler);
             }
 
         });

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerExchangeHandlerRegistry.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerExchangeHandlerRegistry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerExchangeHandlerRegistry.java
deleted file mode 100644
index 67f0cee..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerExchangeHandlerRegistry.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * ====================================================================
- * 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.http.impl.bootstrap;
-
-import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.nio.support.ImmediateResponseExchangeHandler;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.net.URIAuthority;
-import org.apache.hc.core5.util.Args;
-
-public class AsyncServerExchangeHandlerRegistry implements HandlerFactory<AsyncServerExchangeHandler> {
-
-    private final static String LOCALHOST = "localhost";
-
-    private final String canonicalHostName;
-    private final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> primary;
-    private final ConcurrentMap<String, UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>> virtualMap;
-
-    public AsyncServerExchangeHandlerRegistry(final String canonicalHostName) {
-        this.canonicalHostName = Args.notNull(canonicalHostName, "Canonical hostname").toLowerCase(Locale.ROOT);
-        this.primary = new UriPatternMatcher<>();
-        this.virtualMap = new ConcurrentHashMap<>();
-    }
-
-    private UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> getPatternMatcher(final String hostname) {
-        if (hostname == null) {
-            return primary;
-        }
-        if (hostname.equals(canonicalHostName) || hostname.equals(LOCALHOST)) {
-            return primary;
-        }
-        return virtualMap.get(hostname);
-    }
-
-    @Override
-    public AsyncServerExchangeHandler create(final HttpRequest request) throws HttpException {
-        final URIAuthority authority = request.getAuthority();
-        final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
-        final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> patternMatcher = getPatternMatcher(key);
-        if (patternMatcher == null) {
-            return new ImmediateResponseExchangeHandler(HttpStatus.SC_MISDIRECTED_REQUEST, "Not authoritative");
-        }
-        String path = request.getPath();
-        final int i = path.indexOf("?");
-        if (i != -1) {
-            path = path.substring(0, i);
-        }
-        final Supplier<AsyncServerExchangeHandler> supplier = patternMatcher.lookup(path);
-        if (supplier != null) {
-            return supplier.get();
-        }
-        return new ImmediateResponseExchangeHandler(HttpStatus.SC_NOT_FOUND, "Resource not found");
-    }
-
-    public void register(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
-        Args.notBlank(uriPattern, "URI pattern");
-        Args.notNull(supplier, "Supplier");
-        final String key = hostname != null ? hostname.toLowerCase(Locale.ROOT) : null;
-        if (hostname == null || hostname.equals(canonicalHostName) || hostname.equals(LOCALHOST)) {
-            primary.register(uriPattern, supplier);
-        } else {
-            UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> matcher = virtualMap.get(key);
-            if (matcher == null) {
-                final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> newMatcher = new UriPatternMatcher<>();
-                matcher = virtualMap.putIfAbsent(key, newMatcher);
-                if (matcher == null) {
-                    matcher = newMatcher;
-                }
-            }
-            matcher.register(uriPattern, supplier);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
index ef54ee2..84b4516 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
@@ -53,7 +53,7 @@ import org.apache.hc.core5.http.io.HttpConnectionFactory;
 import org.apache.hc.core5.http.io.HttpExpectationVerifier;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.HttpRequestHandlerMapper;
-import org.apache.hc.core5.http.io.UriHttpRequestHandlerMapper;
+import org.apache.hc.core5.http.io.support.UriHttpRequestHandlerMapper;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 
 /**

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/9f39bfdc/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractClassicServerExchangeHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractClassicServerExchangeHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractClassicServerExchangeHandler.java
deleted file mode 100644
index 7589f8d..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractClassicServerExchangeHandler.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * ====================================================================
- * 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.http.impl.nio;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.http.impl.nio.entity.SharedInputBuffer;
-import org.apache.hc.core5.http.impl.nio.entity.SharedOutputBuffer;
-import org.apache.hc.core5.http.message.BasicHttpResponse;
-import org.apache.hc.core5.http.message.HttpResponseWrapper;
-import org.apache.hc.core5.http.nio.HttpContextAware;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.nio.CapacityChannel;
-import org.apache.hc.core5.http.nio.DataStreamChannel;
-import org.apache.hc.core5.http.nio.ResponseChannel;
-import org.apache.hc.core5.http.nio.entity.ContentInputStream;
-import org.apache.hc.core5.http.nio.entity.ContentOutputStream;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-import org.apache.hc.core5.util.Asserts;
-
-/**
- * @since 5.0
- */
-public abstract class AbstractClassicServerExchangeHandler implements HttpContextAware, AsyncServerExchangeHandler {
-
-    private enum State { IDLE, ACTIVE, COMPLETED }
-
-    private final int initialBufferSize;
-    private final Executor executor;
-    private final AtomicReference<State> state;
-    private final AtomicReference<Exception> exception;
-
-    private volatile HttpContext context;
-    private volatile SharedInputBuffer inputBuffer;
-    private volatile SharedOutputBuffer outputBuffer;
-
-    public AbstractClassicServerExchangeHandler(final int initialBufferSize, final Executor executor) {
-        this.initialBufferSize = Args.positive(initialBufferSize, "Initial buffer size");
-        this.executor = Args.notNull(executor, "Executor");
-        this.exception = new AtomicReference<>(null);
-        this.state = new AtomicReference<>(State.IDLE);
-    }
-
-    public Exception getException() {
-        return exception.get();
-    }
-
-    @Override
-    public void setContext(final HttpContext context) {
-        this.context = context;
-    }
-
-    protected abstract void handle(
-            HttpRequest request, InputStream requestStream,
-            HttpResponse response, OutputStream responseStream,
-            HttpContext context) throws IOException, HttpException;
-
-    @Override
-    public final void handleRequest(
-            final HttpRequest request,
-            final EntityDetails entityDetails,
-            final ResponseChannel responseChannel) throws HttpException, IOException {
-
-        if (entityDetails != null) {
-            final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
-            if (h != null && "100-continue".equalsIgnoreCase(h.getValue())) {
-                responseChannel.sendInformation(new BasicHttpResponse(HttpStatus.SC_CONTINUE));
-            }
-        }
-        final AtomicBoolean responseCommitted = new AtomicBoolean(false);
-
-        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
-        final HttpResponse responseWrapper = new HttpResponseWrapper(response){
-
-            private void ensureNotCommitted() {
-                Asserts.check(!responseCommitted.get(), "Response already committed");
-            }
-
-            @Override
-            public void addHeader(final String name, final Object value) {
-                ensureNotCommitted();
-                super.addHeader(name, value);
-            }
-
-            @Override
-            public void setHeader(final String name, final Object value) {
-                ensureNotCommitted();
-                super.setHeader(name, value);
-            }
-
-            @Override
-            public void setVersion(final ProtocolVersion version) {
-                ensureNotCommitted();
-                super.setVersion(version);
-            }
-
-            @Override
-            public void setCode(final int code) {
-                ensureNotCommitted();
-                super.setCode(code);
-            }
-
-            @Override
-            public void setReasonPhrase(final String reason) {
-                ensureNotCommitted();
-                super.setReasonPhrase(reason);
-            }
-
-            @Override
-            public void setLocale(final Locale locale) {
-                ensureNotCommitted();
-                super.setLocale(locale);
-            }
-
-        };
-
-        final InputStream inputStream;
-        if (entityDetails != null) {
-            inputBuffer = new SharedInputBuffer(initialBufferSize);
-            inputStream = new ContentInputStream(inputBuffer);
-        } else {
-            inputStream = null;
-        }
-        outputBuffer = new SharedOutputBuffer(initialBufferSize);
-
-        final OutputStream outputStream = new ContentOutputStream(outputBuffer) {
-
-            private void triggerResponse() throws IOException {
-                try {
-                    if (responseCommitted.compareAndSet(false, true)) {
-                        responseChannel.sendResponse(response, new EntityDetails() {
-
-                            @Override
-                            public long getContentLength() {
-                                return -1;
-                            }
-
-                            @Override
-                            public String getContentType() {
-                                final Header h = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
-                                return h != null ? h.getValue() : null;
-                            }
-
-                            @Override
-                            public String getContentEncoding() {
-                                final Header h = response.getFirstHeader(HttpHeaders.CONTENT_ENCODING);
-                                return h != null ? h.getValue() : null;
-                            }
-
-                            @Override
-                            public boolean isChunked() {
-                                return false;
-                            }
-
-                            @Override
-                            public Set<String> getTrailerNames() {
-                                return null;
-                            }
-
-                        });
-                    }
-                } catch (final HttpException ex) {
-                    throw new IOException(ex.getMessage(), ex);
-                }
-            }
-
-            @Override
-            public void close() throws IOException {
-                triggerResponse();
-                super.close();
-            }
-
-            @Override
-            public void write(final byte[] b, final int off, final int len) throws IOException {
-                triggerResponse();
-                super.write(b, off, len);
-            }
-
-            @Override
-            public void write(final byte[] b) throws IOException {
-                triggerResponse();
-                super.write(b);
-            }
-
-            @Override
-            public void write(final int b) throws IOException {
-                triggerResponse();
-                super.write(b);
-            }
-
-        };
-
-        if (state.compareAndSet(State.IDLE, State.ACTIVE)) {
-            executor.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    try {
-                        handle(request, inputStream, responseWrapper, outputStream, context);
-                        if (inputStream != null) {
-                            inputStream.close();
-                        }
-                        outputStream.close();
-                    } catch (final Exception ex) {
-                        exception.compareAndSet(null, ex);
-                        if (inputBuffer != null) {
-                            inputBuffer.abort();
-                        }
-                        outputBuffer.abort();
-                    } finally {
-                        state.set(State.COMPLETED);
-                    }
-                }
-
-            });
-        }
-    }
-
-    @Override
-    public final void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-        if (inputBuffer != null) {
-            inputBuffer.updateCapacity(capacityChannel);
-        }
-    }
-
-    @Override
-    public final int consume(final ByteBuffer src) throws IOException {
-        Asserts.notNull(inputBuffer, "Input buffer");
-        return inputBuffer.fill(src);
-    }
-
-    @Override
-    public final void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-        Asserts.notNull(inputBuffer, "Input buffer");
-        inputBuffer.markEndStream();
-    }
-
-    @Override
-    public final int available() {
-        Asserts.notNull(outputBuffer, "Output buffer");
-        return outputBuffer.length();
-    }
-
-    @Override
-    public final void produce(final DataStreamChannel channel) throws IOException {
-        Asserts.notNull(outputBuffer, "Output buffer");
-        outputBuffer.flush(channel);
-    }
-
-    @Override
-    public final void failed(final Exception cause) {
-        exception.compareAndSet(null, cause);
-        releaseResources();
-    }
-
-    @Override
-    public void releaseResources() {
-    }
-
-}


Mime
View raw message