Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 79853200CE6 for ; Tue, 1 Aug 2017 21:07:04 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 77F46167C0C; Tue, 1 Aug 2017 19:07:04 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 5B2CA167C08 for ; Tue, 1 Aug 2017 21:07:02 +0200 (CEST) Received: (qmail 29228 invoked by uid 500); 1 Aug 2017 19:07:01 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 29100 invoked by uid 99); 1 Aug 2017 19:06:59 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 Aug 2017 19:06:59 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 3B13BF321C; Tue, 1 Aug 2017 19:06:59 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: olegk@apache.org To: commits@hc.apache.org Date: Tue, 01 Aug 2017 19:07:01 -0000 Message-Id: <0412c78f57db4a6788b5dad1e005b202@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [3/6] httpcomponents-core git commit: Protocol handling API refactoring (no functional changes, mostly moving code to different packages) archived-at: Tue, 01 Aug 2017 19:07:04 -0000 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 Authored: Sat Jul 22 13:40:38 2017 +0200 Committer: Oleg Kalnichevski 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 - * . - * - */ - -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>() { + .register("*", new AsyncServerRequestHandler>() { @Override - public AsyncRequestConsumer> get( + public AsyncRequestConsumer> prepare( final HttpRequest request, final HttpContext context) throws HttpException { return new BasicRequestConsumer<>(new NoopEntityConsumer()); } - }, new ResponseHandler>() { - @Override public void handle( final Message 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 - * . - * - */ - -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 { - - private final UriPatternMatcher> primary; - private final ConcurrentMap>> hostMap; - - public AsyncPushConsumerRegistry() { - this.primary = new UriPatternMatcher<>(); - this.hostMap = new ConcurrentHashMap<>(); - } - - private UriPatternMatcher> getPatternMatcher(final String hostname) { - if (hostname == null) { - return primary; - } - final UriPatternMatcher> 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> 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 supplier = patternMatcher.lookup(path); - if (supplier != null) { - return supplier.get(); - } - return null; - } - - public void register(final String hostname, final String uriPattern, final Supplier 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> matcher = hostMap.get(key); - if (matcher == null) { - final UriPatternMatcher> 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 H2ServerBootstrap register( final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { register(uriPattern, new Supplier() { @Override public AsyncServerExchangeHandler get() { - return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler); + return new BasicServerExchangeHandler<>(requestHandler); } }); @@ -220,13 +218,12 @@ public class H2ServerBootstrap { public final H2ServerBootstrap registerVirtual( final String hostname, final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { registerVirtual(hostname, uriPattern, new Supplier() { @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 + * . + * + */ + +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 { + + private final UriPatternMatcher> primary; + private final ConcurrentMap>> hostMap; + + public AsyncPushConsumerRegistry() { + this.primary = new UriPatternMatcher<>(); + this.hostMap = new ConcurrentHashMap<>(); + } + + private UriPatternMatcher> getPatternMatcher(final String hostname) { + if (hostname == null) { + return primary; + } + final UriPatternMatcher> 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> 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 supplier = patternMatcher.lookup(path); + if (supplier != null) { + return supplier.get(); + } + return null; + } + + public void register(final String hostname, final String uriPattern, final Supplier 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> matcher = hostMap.get(key); + if (matcher == null) { + final UriPatternMatcher> 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 void register( final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { register(uriPattern, new Supplier() { @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 void register( final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { register(uriPattern, new Supplier() { @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 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 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 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 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 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 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 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 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 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> { public MultiLineResponseHandler(final String message, final int count) { - super(new RequestConsumerSupplier>() { + super(new AsyncServerRequestHandler>() { @Override - public AsyncRequestConsumer> get( + public AsyncRequestConsumer> prepare( final HttpRequest request, final HttpContext context) throws HttpException { return new BasicRequestConsumer<>(new StringAsyncEntityConsumer()); } - }, new ResponseHandler>() { - @Override public void handle( final Message 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> { public SingleLineResponseHandler(final String message) { - super(new RequestConsumerSupplier>() { + super(new AsyncServerRequestHandler>() { @Override - public AsyncRequestConsumer> get( + public AsyncRequestConsumer> prepare( final HttpRequest request, final HttpContext context) throws HttpException { return new BasicRequestConsumer<>(new StringAsyncEntityConsumer()); } - }, new ResponseHandler>() { - @Override public void handle( final Message 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>() { + .register("*", new AsyncServerRequestHandler>() { @Override - public AsyncRequestConsumer> get( + public AsyncRequestConsumer> prepare( final HttpRequest request, final HttpContext context) throws HttpException { return new BasicRequestConsumer<>(new NoopEntityConsumer()); } - }, new ResponseHandler>() { - @Override public void handle( final Message 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 AsyncServerBootstrap register( final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { register(uriPattern, new Supplier() { @Override public AsyncServerExchangeHandler get() { - return new BasicServerExchangeHandler<>(consumerSupplier, responseHandler); + return new BasicServerExchangeHandler<>(requestHandler); } }); @@ -198,13 +197,12 @@ public class AsyncServerBootstrap { public final AsyncServerBootstrap registerVirtual( final String hostname, final String uriPattern, - final RequestConsumerSupplier consumerSupplier, - final ResponseHandler responseHandler) { + final AsyncServerRequestHandler requestHandler) { registerVirtual(hostname, uriPattern, new Supplier() { @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 - * . - * - */ - -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 { - - private final static String LOCALHOST = "localhost"; - - private final String canonicalHostName; - private final UriPatternMatcher> primary; - private final ConcurrentMap>> 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> 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> 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 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 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> matcher = virtualMap.get(key); - if (matcher == null) { - final UriPatternMatcher> 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 - * . - * - */ -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; - private final AtomicReference 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 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 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() { - } - -}