You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/08/07 19:13:23 UTC
[3/3] httpcomponents-core git commit: Improved handling of 1xx status
messages by the classic transport;
server expectation (expect-continue) handshake can now be implemented as a
cross-cutting aspect by both the classic and asynchronous transports
Improved handling of 1xx status messages by the classic transport; server expectation (expect-continue) handshake can now be implemented as a cross-cutting aspect by both the classic and asynchronous transports
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/76c3a52e
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/76c3a52e
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/76c3a52e
Branch: refs/heads/master
Commit: 76c3a52e4da2ffdcbfcb58b190503e65fa56ba12
Parents: c7d4ee2
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Tue Aug 1 15:05:34 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Mon Aug 7 21:09:22 2017 +0200
----------------------------------------------------------------------
.../http/examples/Http2FileServerExample.java | 3 +-
.../impl/nio/ClientHttp2StreamHandler.java | 7 +-
.../impl/nio/ClientPushHttp2StreamHandler.java | 5 -
.../impl/nio/ServerHttp2StreamHandler.java | 7 +-
.../impl/nio/bootstrap/H2ServerBootstrap.java | 15 +-
.../testing/classic/ClassicTestServer.java | 17 +-
.../hc/core5/testing/nio/Http1TestServer.java | 26 +-
.../hc/core5/testing/nio/Http2TestServer.java | 42 ++-
.../core5/testing/classic/TestClassicHttp.java | 50 ++--
.../hc/core5/testing/nio/EchoHandler.java | 4 +-
.../core5/testing/nio/Http1IntegrationTest.java | 57 ++--
.../nio/Http1ServerAndRequesterTest.java | 6 +-
.../core5/testing/nio/Http2IntegrationTest.java | 51 ++--
.../testing/nio/MultiLineResponseHandler.java | 3 +-
.../testing/nio/SingleLineResponseHandler.java | 3 +-
.../http/examples/AsyncFileServerExample.java | 3 +-
.../http/examples/AsyncReverseProxyExample.java | 4 +-
.../impl/bootstrap/AsyncServerBootstrap.java | 13 +-
.../http/impl/bootstrap/HttpRequester.java | 30 ++-
.../http/impl/bootstrap/ServerBootstrap.java | 13 +-
.../impl/io/DefaultBHttpClientConnection.java | 5 +
.../core5/http/impl/io/HttpRequestExecutor.java | 107 ++++----
.../hc/core5/http/impl/io/HttpService.java | 262 +++++++++----------
.../http/impl/nio/ClientHttp1StreamHandler.java | 7 +-
.../http/impl/nio/ServerHttp1StreamHandler.java | 9 +-
.../http/io/HttpClientResponseHandler.java | 54 ++++
.../core5/http/io/HttpExpectationVerifier.java | 62 -----
.../io/HttpResponseInformationCallback.java | 44 ++++
.../core5/http/io/HttpServerRequestHandler.java | 57 ++++
.../hc/core5/http/io/ResponseHandler.java | 54 ----
.../BasicHttpServerExpectationDecorator.java | 76 ++++++
.../support/BasicHttpServerRequestHandler.java | 78 ++++++
.../http/nio/AsyncServerExchangeHandler.java | 4 +-
.../http/nio/AsyncServerRequestHandler.java | 13 +-
.../http/nio/AsyncServerResponseTrigger.java | 49 ----
.../hc/core5/http/nio/HttpContextAware.java | 40 ---
.../AbstractClassicServerExchangeHandler.java | 19 +-
.../support/AbstractServerExchangeHandler.java | 71 ++---
.../BasicAsyncServerExpectationDecorator.java | 160 +++++++++++
.../nio/support/BasicServerExchangeHandler.java | 3 +-
...aultAsyncResponseExchangeHandlerFactory.java | 25 +-
.../ImmediateResponseExchangeHandler.java | 4 +-
.../http/impl/io/TestHttpRequestExecutor.java | 64 ++++-
.../hc/core5/http/impl/io/TestHttpService.java | 205 +++++----------
44 files changed, 1056 insertions(+), 775 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 29ed426..1d61ca8 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
@@ -48,7 +48,6 @@ 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;
@@ -132,7 +131,7 @@ public class Http2FileServerExample {
@Override
public void handle(
final Message<HttpRequest, Void> message,
- final AsyncServerResponseTrigger responseTrigger,
+ final ResponseTrigger responseTrigger,
final HttpContext context) throws HttpException, IOException {
HttpRequest request = message.getHead();
URI requestUri;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
index 45cda1c..4bc0987 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
@@ -45,7 +45,6 @@ import org.apache.hc.core5.http.impl.LazyEntityDetails;
import org.apache.hc.core5.http.impl.nio.MessageState;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
import org.apache.hc.core5.http.nio.DataStreamChannel;
-import org.apache.hc.core5.http.nio.HttpContextAware;
import org.apache.hc.core5.http.nio.RequestChannel;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -127,10 +126,6 @@ class ClientHttp2StreamHandler implements Http2StreamHandler {
context.setProtocolVersion(HttpVersion.HTTP_2);
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
- if (exchangeHandler instanceof HttpContextAware) {
- ((HttpContextAware) exchangeHandler).setContext(context);
- }
-
httpProcessor.process(request, entityDetails, context);
final List<Header> headers = DefaultH2RequestConverter.INSTANCE.convert(request);
@@ -191,7 +186,7 @@ class ClientHttp2StreamHandler implements Http2StreamHandler {
if (status < HttpStatus.SC_INFORMATIONAL) {
throw new ProtocolException("Invalid response: " + status);
}
- if (status < HttpStatus.SC_SUCCESS) {
+ if (status > HttpStatus.SC_CONTINUE && status < HttpStatus.SC_SUCCESS) {
exchangeHandler.consumeInformation(response);
}
if (requestState == MessageState.ACK) {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
index 106d88c..abb1f94 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
@@ -43,7 +43,6 @@ import org.apache.hc.core5.http.impl.LazyEntityDetails;
import org.apache.hc.core5.http.impl.nio.MessageState;
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.nio.HttpContextAware;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http2.H2ConnectionException;
@@ -112,10 +111,6 @@ class ClientPushHttp2StreamHandler implements Http2StreamHandler {
context.setProtocolVersion(HttpVersion.HTTP_2);
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
- if (exchangeHandler instanceof HttpContextAware) {
- ((HttpContextAware) exchangeHandler).setContext(context);
- }
-
httpProcessor.process(request, null, context);
connMetrics.incrementRequestCount();
this.requestState = MessageState.COMPLETE;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
index bbd6a56..52ab4a2 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
@@ -46,7 +46,6 @@ import org.apache.hc.core5.http.nio.AsyncPushProducer;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.nio.HttpContextAware;
import org.apache.hc.core5.http.nio.ResponseChannel;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -199,10 +198,6 @@ public class ServerHttp2StreamHandler implements Http2StreamHandler {
context.setProtocolVersion(HttpVersion.HTTP_2);
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
- if (exchangeHandler instanceof HttpContextAware) {
- ((HttpContextAware) exchangeHandler).setContext(context);
- }
-
httpProcessor.process(request, requestEntityDetails, context);
connMetrics.incrementRequestCount();
receivedRequest = request;
@@ -226,7 +221,7 @@ public class ServerHttp2StreamHandler implements Http2StreamHandler {
commitPromise(promise, pushProducer);
}
- });
+ }, context);
break;
case BODY:
responseState = MessageState.COMPLETE;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 0a25098..3e3ddcc 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
@@ -45,6 +45,7 @@ import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.HandlerFactory;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -279,16 +280,24 @@ public class H2ServerBootstrap {
for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
registry.register(entry.hostname, entry.uriPattern, entry.handler);
}
- final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry);
+ final HandlerFactory<AsyncServerExchangeHandler> handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(
+ registry, new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+ return new BasicAsyncServerExpectationDecorator(handler);
+ }
+
+ });
final ServerHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ServerHttp2StreamMultiplexerFactory(
httpProcessor != null ? httpProcessor : Http2Processors.server(),
- exchangeHandlerFactory,
+ handlerFactory,
h2Config != null ? h2Config : H2Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
http2StreamListener);
final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
- exchangeHandlerFactory,
+ handlerFactory,
h1Config != null ? h1Config : H1Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 84937dc..41bb3f8 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
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.H1Config;
@@ -42,10 +43,11 @@ import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.HttpProcessors;
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnectionFactory;
-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.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
+import org.apache.hc.core5.http.io.support.BasicHttpServerExpectationDecorator;
+import org.apache.hc.core5.http.io.support.BasicHttpServerRequestHandler;
import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
import org.apache.hc.core5.io.ShutdownType;
@@ -100,14 +102,13 @@ public class ClassicTestServer {
}
}
- public void start(final HttpProcessor httpProcessor, final HttpExpectationVerifier expectationVerifier) throws IOException {
+ public void start(final HttpProcessor httpProcessor, final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
if (serverRef.get() == null) {
+ final HttpServerRequestHandler handler = new BasicHttpServerRequestHandler(registry);
final HttpService httpService = new HttpService(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
+ handlerDecorator != null ? handlerDecorator.decorate(handler) : new BasicHttpServerExpectationDecorator(handler),
DefaultConnectionReuseStrategy.INSTANCE,
- DefaultClassicHttpResponseFactory.INSTANCE,
- registry,
- expectationVerifier,
LoggingHttp1StreamListener.INSTANCE_CLIENT);
final HttpServer server = new HttpServer(
0,
@@ -129,10 +130,6 @@ public class ClassicTestServer {
}
}
- public void start(final HttpExpectationVerifier expectationVerifier) throws IOException {
- start(null, expectationVerifier);
- }
-
public void start() throws IOException {
start(null, null);
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 9193a05..84bfe18 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
@@ -33,6 +33,7 @@ import java.util.concurrent.Future;
import javax.net.ssl.SSLContext;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.function.Supplier;
import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.H1Config;
@@ -40,6 +41,7 @@ import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.HttpProcessors;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -87,18 +89,34 @@ public class Http1TestServer extends AsyncServer {
return (InetSocketAddress) listener.getAddress();
}
- public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
+ public InetSocketAddress start(
+ final HttpProcessor httpProcessor,
+ final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
+ final H1Config h1Config) throws Exception {
return start(new InternalServerHttp1EventHandlerFactory(
- httpProcessor,
- new DefaultAsyncResponseExchangeHandlerFactory(registry),
+ httpProcessor != null ? httpProcessor : HttpProcessors.server(),
+ new DefaultAsyncResponseExchangeHandlerFactory(
+ registry,
+ exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+ return new BasicAsyncServerExpectationDecorator(handler);
+ }
+
+ }),
h1Config,
CharCodingConfig.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
sslContext));
}
+ public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
+ return start(httpProcessor, null, h1Config);
+ }
+
public InetSocketAddress start() throws Exception {
- return start(HttpProcessors.server(), H1Config.DEFAULT);
+ return start(null, null, H1Config.DEFAULT);
}
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 171f9c0..4bb2443 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
@@ -33,12 +33,14 @@ import java.util.concurrent.Future;
import javax.net.ssl.SSLContext;
+import org.apache.hc.core5.function.Decorator;
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.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -86,10 +88,22 @@ public class Http2TestServer extends AsyncServer {
execute(handlerFactory);
}
- public InetSocketAddress start(final HttpProcessor httpProcessor, final H2Config h2Config) throws Exception {
+ public InetSocketAddress start(
+ final HttpProcessor httpProcessor,
+ final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
+ final H2Config h2Config) throws Exception {
start(new InternalServerHttp2EventHandlerFactory(
- httpProcessor,
- new DefaultAsyncResponseExchangeHandlerFactory(registry),
+ httpProcessor != null ? httpProcessor : Http2Processors.server(),
+ new DefaultAsyncResponseExchangeHandlerFactory(
+ registry,
+ exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+ return new BasicAsyncServerExpectationDecorator(handler);
+ }
+
+ }),
HttpVersionPolicy.FORCE_HTTP_2,
h2Config,
H1Config.DEFAULT,
@@ -100,10 +114,22 @@ public class Http2TestServer extends AsyncServer {
return (InetSocketAddress) listener.getAddress();
}
- public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
+ public InetSocketAddress start(
+ final HttpProcessor httpProcessor,
+ final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
+ final H1Config h1Config) throws Exception {
start(new InternalServerHttp2EventHandlerFactory(
- httpProcessor,
- new DefaultAsyncResponseExchangeHandlerFactory(registry),
+ httpProcessor != null ? httpProcessor : HttpProcessors.server(),
+ new DefaultAsyncResponseExchangeHandlerFactory(
+ registry,
+ exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+ return new BasicAsyncServerExpectationDecorator(handler);
+ }
+
+ }),
HttpVersionPolicy.FORCE_HTTP_1,
H2Config.DEFAULT,
h1Config,
@@ -115,11 +141,11 @@ public class Http2TestServer extends AsyncServer {
}
public InetSocketAddress start(final H2Config h2Config) throws Exception {
- return start(Http2Processors.server(), h2Config);
+ return start(null, null, h2Config);
}
public InetSocketAddress start(final H1Config h1Config) throws Exception {
- return start(HttpProcessors.server(), h1Config);
+ return start(null, null, h1Config);
}
public InetSocketAddress start() throws Exception {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java
index 8d45c2d..f8a3c90 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/TestClassicHttp.java
@@ -39,6 +39,7 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.ContentType;
@@ -53,13 +54,15 @@ import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.config.SocketConfig;
-import org.apache.hc.core5.http.io.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.support.BasicHttpServerExpectationDecorator;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
@@ -452,7 +455,6 @@ public class TestClassicHttp {
}
}
-
/**
* This test case executes a series of simple POST requests that do not
* meet the target server expectations.
@@ -477,28 +479,34 @@ public class TestClassicHttp {
});
- this.server.start(new HttpExpectationVerifier() {
+ this.server.start(null, new Decorator<HttpServerRequestHandler>() {
@Override
- public void verify(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException {
- final Header someheader = request.getFirstHeader("Secret");
- if (someheader != null) {
- final int secretNumber;
- try {
- secretNumber = Integer.parseInt(someheader.getValue());
- } catch (final NumberFormatException ex) {
- response.setCode(HttpStatus.SC_BAD_REQUEST);
- return;
- }
- if (secretNumber >= 2) {
- response.setCode(HttpStatus.SC_EXPECTATION_FAILED);
- response.setEntity(
- new StringEntity("Wrong secret number", ContentType.TEXT_PLAIN));
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler handler) {
+ return new BasicHttpServerExpectationDecorator(handler) {
+
+ @Override
+ protected ClassicHttpResponse verify(final ClassicHttpRequest request, final HttpContext context) {
+ final Header someheader = request.getFirstHeader("Secret");
+ if (someheader != null) {
+ final int secretNumber;
+ try {
+ secretNumber = Integer.parseInt(someheader.getValue());
+ } catch (final NumberFormatException ex) {
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST);
+ response.setEntity(new StringEntity(ex.toString()));
+ return response;
+ }
+ if (secretNumber >= 2) {
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
+ response.setEntity(new StringEntity("Wrong secret number", ContentType.TEXT_PLAIN));
+ return response;
+ }
+ }
+ return null;
}
- }
+
+ };
}
});
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
index 5b82f0e..f7962cc 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
@@ -42,6 +42,7 @@ 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.protocol.HttpContext;
public class EchoHandler implements AsyncServerExchangeHandler {
@@ -67,7 +68,8 @@ public class EchoHandler implements AsyncServerExchangeHandler {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
if (entityDetails != null) {
final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
if (h != null && "100-continue".equalsIgnoreCase(h.getValue())) {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 825fb6f..2ad7661 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
@@ -58,6 +58,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.function.Supplier;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.ContentLengthStrategy;
@@ -91,7 +92,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.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.BasicRequestConsumer;
import org.apache.hc.core5.http.nio.BasicRequestProducer;
import org.apache.hc.core5.http.nio.BasicResponseConsumer;
@@ -113,6 +114,7 @@ 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.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -697,9 +699,26 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
@Override
- protected AsyncResponseProducer verify(
- final HttpRequest request,
+ protected void handle(
+ final Message<HttpRequest, String> request,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
+ responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
+
+ }
+ };
+ }
+
+ });
+ final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+
+ return new BasicAsyncServerExpectationDecorator(handler) {
+
+ @Override
+ protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
final Header h = request.getFirstHeader("password");
if (h != null && "secret".equals(h.getValue())) {
return null;
@@ -707,21 +726,10 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
}
}
-
- @Override
- protected void handle(
- final Message<HttpRequest, String> request,
- final AsyncServerResponseTrigger responseTrigger,
- final HttpContext context) throws IOException, HttpException {
- responseTrigger.submitResponse(
- new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
-
- }
};
- }
- });
- final InetSocketAddress serverEndpoint = server.start();
+ }
+ }, H1Config.DEFAULT);
client.start();
final Future<IOSession> sessionFuture = client.requestSession(
@@ -805,7 +813,8 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
@@ -906,7 +915,8 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
final AsyncResponseProducer producer;
final Header h = request.getFirstHeader("password");
if (h != null && "secret".equals(h.getValue())) {
@@ -1356,7 +1366,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, String> request,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
responseTrigger.submitResponse(
new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")));
@@ -1440,7 +1450,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, String> request,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
throw new HttpException("Boom");
}
@@ -1499,7 +1509,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, String> request,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT);
responseTrigger.submitResponse(new BasicResponseProducer(response));
@@ -1586,7 +1596,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, String> requestMessage,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws HttpException, IOException {
responseTrigger.submitResponse(new BasicResponseProducer(
HttpStatus.SC_OK,
@@ -1648,7 +1658,8 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
final String requestUri = request.getRequestUri();
if (requestUri.endsWith("boom")) {
throw new ProtocolException("Boom!!!");
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
index ba736e4..96a975c 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
@@ -57,6 +57,7 @@ import org.apache.hc.core5.http.nio.BasicResponseConsumer;
import org.apache.hc.core5.http.nio.ResponseChannel;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.io.ShutdownType;
import org.apache.hc.core5.reactor.ExceptionEvent;
import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -102,7 +103,8 @@ public class Http1ServerAndRequesterTest {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
super.handleRequest(request, entityDetails, new ResponseChannel() {
@Override
@@ -125,7 +127,7 @@ public class Http1ServerAndRequesterTest {
responseChannel.pushPromise(promise, pushProducer);
}
- });
+ }, context);
}
};
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 3b105c0..86a95ac 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
@@ -61,6 +61,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.hc.core5.function.Callback;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.function.Supplier;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EndpointDetails;
@@ -82,7 +83,7 @@ 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.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.BasicPushProducer;
import org.apache.hc.core5.http.nio.BasicRequestConsumer;
import org.apache.hc.core5.http.nio.BasicRequestProducer;
@@ -102,6 +103,7 @@ 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.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http2.H2Error;
import org.apache.hc.core5.http2.H2StreamResetException;
@@ -576,7 +578,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, Void> request,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
responseTrigger.pushPromise(
new BasicHttpRequest("GET", createRequestURI(serverEndpoint, "/stuff")),
@@ -656,7 +658,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, Void> request,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
responseTrigger.pushPromise(
@@ -760,12 +762,29 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
@Override
public AsyncServerExchangeHandler get() {
- return new MessageExchangeHandler<Void>(new NoopEntityConsumer()) {
+ return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
@Override
- protected AsyncResponseProducer verify(
- final HttpRequest request,
+ protected void handle(
+ final Message<HttpRequest, String> request,
+ final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
final HttpContext context) throws IOException, HttpException {
+ responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
+
+ }
+ };
+ }
+
+ });
+ final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+
+ return new BasicAsyncServerExpectationDecorator(handler) {
+
+ @Override
+ protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
final Header h = request.getFirstHeader("password");
if (h != null && "secret".equals(h.getValue())) {
return null;
@@ -773,21 +792,10 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
}
}
-
- @Override
- protected void handle(
- final Message<HttpRequest, Void> request,
- final AsyncServerResponseTrigger responseTrigger,
- final HttpContext context) throws IOException, HttpException {
- responseTrigger.submitResponse(
- new BasicResponseProducer(HttpStatus.SC_OK, "All is well"));
-
- }
};
- }
- });
- final InetSocketAddress serverEndpoint = server.start();
+ }
+ }, H2Config.DEFAULT);
client.start();
final Future<ClientSessionEndpoint> connectFuture = client.connect(
@@ -846,7 +854,8 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
public void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
final AsyncResponseProducer producer;
final Header h = request.getFirstHeader("password");
if (h != null && "secret".equals(h.getValue())) {
@@ -917,7 +926,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
@Override
protected void handle(
final Message<HttpRequest, String> requestMessage,
- final AsyncServerResponseTrigger responseTrigger,
+ final AsyncServerRequestHandler.ResponseTrigger 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/76c3a52e/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 4e025d4..1bbaaf0 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
@@ -36,7 +36,6 @@ 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;
@@ -58,7 +57,7 @@ public class MultiLineResponseHandler extends BasicServerExchangeHandler<Message
@Override
public void handle(
final Message<HttpRequest, String> requestMessage,
- final AsyncServerResponseTrigger responseTrigger,
+ final ResponseTrigger 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/76c3a52e/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 af8d453..e0cbe2c 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
@@ -34,7 +34,6 @@ 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;
@@ -57,7 +56,7 @@ public class SingleLineResponseHandler extends BasicServerExchangeHandler<Messag
@Override
public void handle(
final Message<HttpRequest, String> requestMessage,
- final AsyncServerResponseTrigger responseTrigger,
+ final ResponseTrigger 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/76c3a52e/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 ed0c077..9a00868 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
@@ -46,7 +46,6 @@ 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;
@@ -94,7 +93,7 @@ public class AsyncFileServerExample {
@Override
public void handle(
final Message<HttpRequest, Void> message,
- final AsyncServerResponseTrigger responseTrigger,
+ final ResponseTrigger responseTrigger,
final HttpContext context) throws HttpException, IOException {
HttpRequest request = message.getHead();
URI requestUri;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
index e66efcb..d0e7006 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
@@ -72,6 +72,7 @@ import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.RequestChannel;
import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.io.ShutdownType;
import org.apache.hc.core5.pool.ConnPoolListener;
import org.apache.hc.core5.pool.ConnPoolStats;
@@ -264,7 +265,8 @@ public class AsyncReverseProxyExample {
public void handleRequest(
final HttpRequest incomingRequest,
final EntityDetails entityDetails,
- final ResponseChannel responseChannel) throws HttpException, IOException {
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
synchronized (exchangeState) {
System.out.println("[client->proxy] " + exchangeState.id + " " +
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 8e5be10..d58d9ae 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
@@ -44,8 +44,10 @@ 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.HandlerFactory;
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.BasicAsyncServerExpectationDecorator;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -255,9 +257,18 @@ public class AsyncServerBootstrap {
for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
registry.register(entry.hostname, entry.uriPattern, entry.handler);
}
+ final HandlerFactory<AsyncServerExchangeHandler> handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(
+ registry, new Decorator<AsyncServerExchangeHandler>() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+ return new BasicAsyncServerExpectationDecorator(handler);
+ }
+
+ });
final ServerHttp1StreamDuplexerFactory streamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
- new DefaultAsyncResponseExchangeHandlerFactory(registry),
+ handlerFactory,
h1Config != null ? h1Config : H1Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
connStrategy != null ? connStrategy : DefaultConnectionReuseStrategy.INSTANCE,
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
index 039e98b..22ec655 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
@@ -55,8 +55,9 @@ import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.io.EofSensorInputStream;
import org.apache.hc.core5.http.io.EofSensorWatcher;
import org.apache.hc.core5.http.io.HttpClientConnection;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.io.HttpConnectionFactory;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpResponseInformationCallback;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.HttpEntityWrapper;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -100,6 +101,7 @@ public class HttpRequester implements GracefullyCloseable {
public ClassicHttpResponse execute(
final HttpClientConnection connection,
final ClassicHttpRequest request,
+ final HttpResponseInformationCallback informationCallback,
final HttpContext context) throws HttpException, IOException {
Args.notNull(connection, "HTTP connection");
Args.notNull(request, "HTTP request");
@@ -108,11 +110,18 @@ public class HttpRequester implements GracefullyCloseable {
throw new ConnectionClosedException("Connection is closed");
}
requestExecutor.preProcess(request, httpProcessor, context);
- final ClassicHttpResponse response = requestExecutor.execute(request, connection, context);
+ final ClassicHttpResponse response = requestExecutor.execute(request, connection, informationCallback, context);
requestExecutor.postProcess(response, httpProcessor, context);
return response;
}
+ public ClassicHttpResponse execute(
+ final HttpClientConnection connection,
+ final ClassicHttpRequest request,
+ final HttpContext context) throws HttpException, IOException {
+ return execute(connection, request, null, context);
+ }
+
public boolean keepAlive(
final HttpClientConnection connection,
final ClassicHttpRequest request,
@@ -129,7 +138,7 @@ public class HttpRequester implements GracefullyCloseable {
final HttpClientConnection connection,
final ClassicHttpRequest request,
final HttpContext context,
- final ResponseHandler<T> responseHandler) throws HttpException, IOException {
+ final HttpClientResponseHandler<T> responseHandler) throws HttpException, IOException {
try (final ClassicHttpResponse response = execute(connection, request, context)) {
final T result = responseHandler.handleResponse(response);
EntityUtils.consume(response.getEntity());
@@ -188,6 +197,7 @@ public class HttpRequester implements GracefullyCloseable {
public ClassicHttpResponse execute(
final HttpHost targetHost,
final ClassicHttpRequest request,
+ final HttpResponseInformationCallback informationCallback,
final Timeout connectTimeout,
final HttpContext context) throws HttpException, IOException {
Args.notNull(targetHost, "HTTP host");
@@ -212,7 +222,7 @@ public class HttpRequester implements GracefullyCloseable {
connection = connectFactory.createConnection(socket);
poolEntry.assignConnection(connection);
}
- final ClassicHttpResponse response = execute(connection, request, context);
+ final ClassicHttpResponse response = execute(connection, request, informationCallback, context);
final HttpEntity entity = response.getEntity();
if (entity != null) {
response.setEntity(new HttpEntityWrapper(entity) {
@@ -302,13 +312,21 @@ public class HttpRequester implements GracefullyCloseable {
}
}
+ public ClassicHttpResponse execute(
+ final HttpHost targetHost,
+ final ClassicHttpRequest request,
+ final Timeout connectTimeout,
+ final HttpContext context) throws HttpException, IOException {
+ return execute(targetHost, request, null, connectTimeout, context);
+ }
+
public <T> T execute(
final HttpHost targetHost,
final ClassicHttpRequest request,
final Timeout connectTimeout,
final HttpContext context,
- final ResponseHandler<T> responseHandler) throws HttpException, IOException {
- try (final ClassicHttpResponse response = execute(targetHost, request, connectTimeout, context)) {
+ final HttpClientResponseHandler<T> responseHandler) throws HttpException, IOException {
+ try (final ClassicHttpResponse response = execute(targetHost, request, null, connectTimeout, context)) {
final T result = responseHandler.handleResponse(response);
EntityUtils.consume(response.getEntity());
return result;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/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 4bdbba7..c9a1452 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
@@ -50,7 +50,6 @@ import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnectionFactory;
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.HttpConnectionFactory;
-import org.apache.hc.core5.http.io.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
@@ -74,7 +73,6 @@ public class ServerBootstrap {
private HttpProcessor httpProcessor;
private ConnectionReuseStrategy connStrategy;
private HttpResponseFactory<ClassicHttpResponse> responseFactory;
- private HttpExpectationVerifier expectationVerifier;
private ServerSocketFactory serverSocketFactory;
private SSLContext sslContext;
private SSLServerSetupHandler sslSetupHandler;
@@ -203,14 +201,6 @@ public class ServerBootstrap {
}
/**
- * Assigns {@link HttpExpectationVerifier} instance.
- */
- public final ServerBootstrap setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
- this.expectationVerifier = expectationVerifier;
- return this;
- }
-
- /**
* Assigns {@link HttpConnectionFactory} instance.
*/
public final ServerBootstrap setConnectionFactory(
@@ -286,8 +276,7 @@ public class ServerBootstrap {
}
final HttpService httpService = new HttpService(
- httpProcessorCopy, connStrategyCopy, responseFactoryCopy, requestHandlerRegistry,
- this.expectationVerifier, this.streamListener);
+ httpProcessorCopy, requestHandlerRegistry, connStrategyCopy, responseFactoryCopy, this.streamListener);
ServerSocketFactory serverSocketFactoryCopy = this.serverSocketFactory;
if (serverSocketFactoryCopy == null) {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
index 00da305..9036caa 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
@@ -41,6 +41,7 @@ import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.LengthRequiredException;
+import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
import org.apache.hc.core5.http.config.H1Config;
@@ -189,6 +190,10 @@ public class DefaultBHttpClientConnection extends BHttpConnectionBase
}
this.version = transportVersion;
onResponseReceived(response);
+ final int status = response.getCode();
+ if (status < HttpStatus.SC_INFORMATIONAL) {
+ throw new ProtocolException("Invalid response: " + status);
+ }
if (response.getCode() >= HttpStatus.SC_SUCCESS) {
incrementResponseCount();
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/76c3a52e/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
index d6bc0da..ac36432 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
@@ -39,11 +39,12 @@ import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.io.HttpClientConnection;
+import org.apache.hc.core5.http.io.HttpResponseInformationCallback;
+import org.apache.hc.core5.http.message.MessageSupport;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http.protocol.HttpProcessor;
@@ -95,34 +96,13 @@ public class HttpRequestExecutor {
}
/**
- * Decide whether a response comes with an entity.
- * The implementation in this class is based on RFC 2616.
- * <p>
- * Derived executors can override this method to handle
- * methods and response codes not specified in RFC 2616.
- * </p>
- *
- * @param request the request, to obtain the executed method
- * @param response the response, to obtain the status code
- */
- protected boolean canResponseHaveBody(final ClassicHttpRequest request,
- final ClassicHttpResponse response) {
-
- if ("HEAD".equalsIgnoreCase(request.getMethod())) {
- return false;
- }
- final int status = response.getCode();
- return status >= HttpStatus.SC_SUCCESS
- && status != HttpStatus.SC_NO_CONTENT
- && status != HttpStatus.SC_NOT_MODIFIED;
- }
-
- /**
* Sends the request and obtain a response.
*
* @param request the request to execute.
* @param conn the connection over which to execute the request.
- *
+ * @param informationCallback callback to execute upon receipt of information status (1xx).
+ * May be null.
+ * @param context the context
* @return the response to the request.
*
* @throws IOException in case of an I/O error.
@@ -132,13 +112,12 @@ public class HttpRequestExecutor {
public ClassicHttpResponse execute(
final ClassicHttpRequest request,
final HttpClientConnection conn,
+ final HttpResponseInformationCallback informationCallback,
final HttpContext context) throws IOException, HttpException {
Args.notNull(request, "HTTP request");
Args.notNull(conn, "Client connection");
Args.notNull(context, "HTTP context");
try {
- ClassicHttpResponse response = null;
-
context.setAttribute(HttpCoreContext.SSL_SESSION, conn.getSSLSession());
context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, conn.getEndpointDetails());
@@ -146,50 +125,61 @@ public class HttpRequestExecutor {
if (streamListener != null) {
streamListener.onRequestHead(conn, request);
}
+ boolean expectContinue = false;
final HttpEntity entity = request.getEntity();
if (entity != null) {
final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
- final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
+ expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
+ if (!expectContinue) {
+ conn.sendRequestEntity(request);
+ }
+ }
+ conn.flush();
+ ClassicHttpResponse response = null;
+ while (response == null) {
if (expectContinue) {
-
- conn.flush();
- // Don't wait for a 100-continue response forever. On timeout, send the entity.
if (conn.isDataAvailable(this.waitForContinue)) {
response = conn.receiveResponseHeader();
if (streamListener != null) {
streamListener.onResponseHead(conn, response);
}
final int status = response.getCode();
- if (status < HttpStatus.SC_SUCCESS) {
- if (status != HttpStatus.SC_CONTINUE) {
- throw new ProtocolException("Unexpected response: " + response.getCode());
- }
+ if (status == HttpStatus.SC_CONTINUE) {
// discard 100-continue
response = null;
conn.sendRequestEntity(request);
- } else {
- if (canResponseHaveBody(request, response)) {
- conn.receiveResponseEntity(response);
+ } else if (status < HttpStatus.SC_SUCCESS) {
+ if (informationCallback != null) {
+ informationCallback.execute(response, conn, context);
}
+ response = null;
+ continue;
+ } else if (status >= HttpStatus.SC_CLIENT_ERROR){
conn.terminateRequest(request);
+ } else {
+ conn.sendRequestEntity(request);
}
} else {
conn.sendRequestEntity(request);
}
+ conn.flush();
+ expectContinue = false;
} else {
- conn.sendRequestEntity(request);
+ response = conn.receiveResponseHeader();
+ if (streamListener != null) {
+ streamListener.onResponseHead(conn, response);
+ }
+ final int status = response.getCode();
+ if (status < HttpStatus.SC_SUCCESS) {
+ if (informationCallback != null && status != HttpStatus.SC_CONTINUE) {
+ informationCallback.execute(response, conn, context);
+ }
+ response = null;
+ }
}
}
- conn.flush();
-
- while (response == null || response.getCode() < HttpStatus.SC_OK) {
- response = conn.receiveResponseHeader();
- if (streamListener != null) {
- streamListener.onResponseHead(conn, response);
- }
- if (canResponseHaveBody(request, response)) {
- conn.receiveResponseEntity(response);
- }
+ if (MessageSupport.canResponseHaveBody(request.getMethod(), response)) {
+ conn.receiveResponseEntity(response);
}
return response;
@@ -199,6 +189,25 @@ public class HttpRequestExecutor {
}
}
+ /**
+ * Sends the request and obtain a response.
+ *
+ * @param request the request to execute.
+ * @param conn the connection over which to execute the request.
+ * @param context the context
+ * @return the response to the request.
+ *
+ * @throws IOException in case of an I/O error.
+ * @throws HttpException in case of HTTP protocol violation or a processing
+ * problem.
+ */
+ public ClassicHttpResponse execute(
+ final ClassicHttpRequest request,
+ final HttpClientConnection conn,
+ final HttpContext context) throws IOException, HttpException {
+ return execute(request, conn, null, context);
+ }
+
private static void closeConnection(final HttpClientConnection conn) {
try {
conn.close();