Made HttpCoreContext consistent with the behavior of HttpContext implementations in HttpClient
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamMultiplexer.java
index 36f0262..b785009 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamMultiplexer.java
@@ -111,7 +111,7 @@ H2StreamHandler createLocallyInitiatedStream(
final RequestExecutionCommand executionCommand = (RequestExecutionCommand) command;
final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory = executionCommand.getPushHandlerFactory();
- final HttpCoreContext context = HttpCoreContext.cast(executionCommand.getContext());
+ final HttpCoreContext context = HttpCoreContext.castOrCreate(executionCommand.getContext());
context.setSSLSession(getSSLSession());
context.setEndpointDetails(getEndpointDetails());
return new ClientH2StreamHandler(channel, httpProcessor, connMetrics, exchangeHandler,
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 c190ec9..e97f79f 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
@@ -140,7 +140,7 @@ public ClassicHttpResponse execute(
Args.notNull(request, "HTTP request");
Args.notNull(conn, "Client connection");
Args.notNull(localContext, "HTTP context");
- final HttpCoreContext context = HttpCoreContext.cast(localContext);
+ final HttpCoreContext context = HttpCoreContext.castOrCreate(localContext);
try {
context.setSSLSession(conn.getSSLSession());
context.setEndpointDetails(conn.getEndpointDetails());
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
index 0ed4af9..7299d72 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
@@ -309,7 +309,7 @@ void outputEnd() throws HttpException, IOException {
@Override
void execute(final RequestExecutionCommand executionCommand) throws HttpException, IOException {
final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
- final HttpCoreContext context = HttpCoreContext.cast(executionCommand.getContext());
+ final HttpCoreContext context = HttpCoreContext.castOrCreate(executionCommand.getContext());
context.setSSLSession(getSSLSession());
context.setEndpointDetails(getEndpointDetails());
final ClientHttp1StreamHandler handler = new ClientHttp1StreamHandler(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/HttpCoreContext.java b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/HttpCoreContext.java
index 619be1f..1439261 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/HttpCoreContext.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/HttpCoreContext.java
@@ -93,17 +93,29 @@ public static HttpCoreContext adapt(final HttpContext context) {
}
/**
- * Casts the given generic {@link HttpContext} as {@link HttpCoreContext}
- * or creates a new {@link HttpCoreContext} with the given {@link HttpContext}
- * as a parent.
+ * Casts the given generic {@link HttpContext} as {@link HttpCoreContext}.
*
* @since 5.3
*/
public static HttpCoreContext cast(final HttpContext context) {
+ if (context == null) {
+ return null;
+ }
if (context instanceof HttpCoreContext) {
return (HttpCoreContext) context;
+ } else {
+ return new Delegate(context);
}
- return new HttpCoreContext(context);
+ }
+
+ /**
+ * Casts the given generic {@link HttpContext} as {@link HttpCoreContext} or
+ * creates new {@link HttpCoreContext} if the given context is null.
+ *
+ * @since 5.4
+ */
+ public static HttpCoreContext castOrCreate(final HttpContext context) {
+ return context != null ? cast(context) : create();
}
private final HttpContext parentContext;
@@ -254,6 +266,106 @@ public void setSSLSession(final SSLSession sslSession) {
this.sslSession = sslSession;
}
+ /**
+ * Internal adaptor class that delegates all its method calls to a plain {@link HttpContext}.
+ * To be removed in the future.
+ */
+ @SuppressWarnings("deprecation")
+ @Internal
+ static class Delegate extends HttpCoreContext {
+
+ private final HttpContext httpContext;
+
+ Delegate(final HttpContext httpContext) {
+ super(null);
+ this.httpContext = httpContext;
+ }
+
+ <T> T getAttr(final String id, final Class<T> clazz) {
+ final Object obj = httpContext.getAttribute(id);
+ if (obj == null) {
+ return null;
+ }
+ return clazz.cast(obj);
+ }
+
+ @Override
+ public HttpRequest getRequest() {
+ return getAttr(HTTP_REQUEST, HttpRequest.class);
+ }
+
+ @Override
+ public void setRequest(final HttpRequest request) {
+ httpContext.setAttribute(HTTP_REQUEST, request);
+ }
+
+ @Override
+ public HttpResponse getResponse() {
+ return getAttr(HTTP_RESPONSE, HttpResponse.class);
+ }
+
+ @Override
+ public void setResponse(final HttpResponse response) {
+ httpContext.setAttribute(HTTP_RESPONSE, response);
+ }
+
+ @Override
+ public EndpointDetails getEndpointDetails() {
+ return getAttr(CONNECTION_ENDPOINT, EndpointDetails.class);
+ }
+
+ @Override
+ public void setEndpointDetails(final EndpointDetails endpointDetails) {
+ httpContext.setAttribute(CONNECTION_ENDPOINT, endpointDetails);
+ }
+
+ @Override
+ public SSLSession getSSLSession() {
+ return getAttr(SSL_SESSION, SSLSession.class);
+ }
+
+ @Override
+ public void setSSLSession(final SSLSession sslSession) {
+ httpContext.setAttribute(SSL_SESSION, sslSession);
+ }
+
+ @Override
+ public ProtocolVersion getProtocolVersion() {
+ return httpContext.getProtocolVersion();
+ }
+
+ @Override
+ public void setProtocolVersion(final ProtocolVersion version) {
+ httpContext.setProtocolVersion(version);
+ }
+
+ @Override
+ public Object getAttribute(final String id) {
+ return httpContext.getAttribute(id);
+ }
+
+ @Override
+ public Object setAttribute(final String id, final Object obj) {
+ return httpContext.setAttribute(id, obj);
+ }
+
+ @Override
+ public Object removeAttribute(final String id) {
+ return httpContext.removeAttribute(id);
+ }
+
+ @Override
+ public <T> T getAttribute(final String id, final Class<T> clazz) {
+ return getAttr(id, clazz);
+ }
+
+ @Override
+ public String toString() {
+ return httpContext.toString();
+ }
+
+ }
+
@Override
public String toString() {
return "HttpCoreContext{" +