[java-support] branch master updated: OSJ-265: TLS socket factory clears client TLS credential too early
Brent Putman
putmanb at georgetown.edu
Fri Mar 22 19:30:12 EDT 2019
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch master
in repository java-support.
View the commit online:
http://git.shibboleth.net/view/?p=java-support.git;a=commit;h=cab2143c8460ac77ad4dc1ee4fdee8c26438a52b
The following commit(s) were added to refs/heads/master by this push:
new cab2143 OSJ-265: TLS socket factory clears client TLS credential too early
cab2143 is described below
commit cab2143c8460ac77ad4dc1ee4fdee8c26438a52b
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Wed Mar 13 20:04:46 2019 -0400
OSJ-265: TLS socket factory clears client TLS credential too early
This changes introduces a new feature of the HttpClient instances
produced by HttpClientBuilder. The clients now automatically invoke
instances of HttpClientContextHandler supplied either statically on
the builder and/or dynamically via the HttpClientContext.
---
.../httpclient/ContextHandlingHttpClient.java | 379 ++++
.../java/support/httpclient/HttpClientBuilder.java | 45 +-
.../java/support/httpclient/HttpClientSupport.java | 53 +
.../httpclient/ContextHandlingHttpClientTest.java | 1962 ++++++++++++++++++++
.../support/httpclient/HttpClientBuilderTest.java | 55 +
.../support/httpclient/HttpClientSupportTest.java | 76 +
6 files changed, 2559 insertions(+), 11 deletions(-)
diff --git a/src/main/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClient.java b/src/main/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClient.java
new file mode 100644
index 0000000..a90e544
--- /dev/null
+++ b/src/main/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClient.java
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+package net.shibboleth.utilities.java.support.httpclient;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpRequestWrapper;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+import net.shibboleth.utilities.java.support.collection.LazyList;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * A wrapper implementation of {@link HttpClient} which invokes supplied instances of {@link HttpClientContextHandler}
+ * before and after request execution.
+ *
+ * <p>
+ * By definition the handlers will only be invoked for the {@link HttpClient} execute(...) method variants
+ * which take an {@link HttpContext} argument.
+ * </p>
+ *
+ * <p>
+ * The order of execution is:
+ * <ol>
+ * <li>Static handlers supplied via the constructor, in original list order</li>
+ * <li>Dynamic handlers from the context attribute {@link HttpClientSupport#CONTEXT_KEY_DYNAMIC_CONTEXT_HANDLERS},
+ * in original list order</li>
+ * <li>the wrapped client's corresponding execute(...) method</li>
+ * <li>Dynamic handlers from the context attribute {@link HttpClientSupport#CONTEXT_KEY_DYNAMIC_CONTEXT_HANDLERS},
+ * in reverse list order</li>
+ * <li>Static handlers supplied via the constructor, in reverse list order</li>
+ * </ol>
+ * </p>
+ */
+class ContextHandlingHttpClient implements HttpClient {
+
+ /** Logger. */
+ private Logger log = LoggerFactory.getLogger(ContextHandlingHttpClient.class);
+
+ /** The wrapped client instance. */
+ @Nonnull private HttpClient httpClient;
+
+ /** Optional list of static handlers supplied to this class instance. */
+ @Nonnull private List<HttpClientContextHandler> handlers;
+
+ /**
+ * Constructor.
+ *
+ * @param client the wrapped client instance
+ */
+ public ContextHandlingHttpClient(@Nonnull final HttpClient client) {
+ this(client, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param client the wrapped client instance
+ * @param staticHandlers the list of static handlers
+ */
+ public ContextHandlingHttpClient(@Nonnull final HttpClient client,
+ @Nonnull final List<HttpClientContextHandler> staticHandlers) {
+ httpClient = Constraint.isNotNull(client, "HttpClient was null");
+ handlers = staticHandlers != null ? staticHandlers : Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ public HttpParams getParams() {
+ return httpClient.getParams();
+ }
+
+ /** {@inheritDoc} */
+ public ClientConnectionManager getConnectionManager() {
+ return httpClient.getConnectionManager();
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(final HttpUriRequest request) throws IOException, ClientProtocolException {
+ return httpClient.execute(request);
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(final HttpHost target, final HttpRequest request)
+ throws IOException, ClientProtocolException {
+ return httpClient.execute(target, request);
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(final HttpUriRequest request, final ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
+ return httpClient.execute(request, responseHandler);
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(final HttpHost target, final HttpRequest request,
+ final ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
+ return httpClient.execute(target, request, responseHandler);
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(final HttpUriRequest uriRequest, final HttpContext context)
+ throws IOException, ClientProtocolException {
+
+ Throwable error = null;
+
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ try {
+ invokeBefore(uriRequest, clientContext);
+ return httpClient.execute(uriRequest, context);
+ } catch (final Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ invokeAfter(uriRequest, clientContext, error);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(final HttpHost target, final HttpRequest request, final HttpContext context)
+ throws IOException, ClientProtocolException {
+
+ Throwable error = null;
+
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ final HttpUriRequest uriRequest = HttpUriRequest.class.isInstance(request)
+ ? (HttpUriRequest)request : HttpRequestWrapper.wrap(request, target);
+ try {
+ invokeBefore(uriRequest, clientContext);
+ return httpClient.execute(target, request, context);
+ } catch (final Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ invokeAfter(uriRequest, clientContext, error);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(final HttpUriRequest uriRequest, final ResponseHandler<? extends T> responseHandler,
+ final HttpContext context) throws IOException, ClientProtocolException {
+
+ Throwable error = null;
+
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ try {
+ invokeBefore(uriRequest, clientContext);
+ return httpClient.execute(uriRequest, responseHandler, context);
+ } catch (final Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ invokeAfter(uriRequest, clientContext, error);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(final HttpHost target, final HttpRequest request,
+ final ResponseHandler<? extends T> responseHandler, final HttpContext context)
+ throws IOException, ClientProtocolException {
+
+ Throwable error = null;
+
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ final HttpUriRequest uriRequest = HttpUriRequest.class.isInstance(request)
+ ? (HttpUriRequest)request : HttpRequestWrapper.wrap(request, target);
+ try {
+ invokeBefore(uriRequest, clientContext);
+ return httpClient.execute(target, request, responseHandler, context);
+ } catch (final Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ invokeAfter(uriRequest, clientContext, error);
+ }
+ }
+
+ /**
+ * Invoke {@link HttpClientContextHandler#invokeBefore(HttpClientContext, HttpUriRequest)}
+ * for supplied handlers.
+ *
+ * @param request the HTTP request
+ * @param context the HTTP context
+ * @throws IOException if any handler throws an error
+ */
+ private void invokeBefore(final HttpUriRequest request, final HttpClientContext context) throws IOException {
+ log.trace("In invokeBefore");
+
+ final List<Throwable> errors = new LazyList<>();
+
+ for (final HttpClientContextHandler handler : handlers) {
+ try {
+ if (handler != null) {
+ log.trace("Invoking static handler invokeBefore: {}", handler.getClass().getName());
+ handler.invokeBefore(context, request);
+ }
+ } catch (final Throwable t) {
+ log.warn("Static handler invokeBefore threw: {}", handler.getClass().getName(), t);
+ errors.add(t);
+ }
+ }
+
+ for (final HttpClientContextHandler handler
+ : HttpClientSupport.getDynamicContextHandlerList(context)) {
+ try {
+ if (handler != null) {
+ log.trace("Invoking dynamic handler invokeBefore: {}", handler.getClass().getName());
+ handler.invokeBefore(context, request);
+ }
+ } catch (final Throwable t) {
+ log.warn("Dynamic handler invokeBefore threw: {}", handler.getClass().getName(), t);
+ errors.add(t);
+ }
+ }
+
+ final IOException exception = processHandlerErrors("Invoke Before", errors);
+ if (exception != null) {
+ throw exception;
+ }
+
+ }
+
+ /**
+ * Invoke {@link HttpClientContextHandler#invokeAfter(HttpClientContext, HttpUriRequest)}
+ * for all supplied handlers.
+ *
+ * @param request the HTTP request
+ * @param context the HTTP context
+ * @param priorError an error thrown by by either {@link #invokeBefore(HttpUriRequest, HttpClientContext)}
+ * or by HttpClient execute(...).
+ *
+ * @throws IOException if any handler throws an error, or if priorError is an IOException. If priorError
+ * is a type of unchecked error (RuntimeException or Error) that will be propagated out
+ * here as well.
+ */
+ private void invokeAfter(final HttpUriRequest request, final HttpClientContext context,
+ final Throwable priorError) throws IOException {
+ log.trace("In invokeAfter");
+
+ final List<Throwable> errors = new LazyList<>();
+
+ for (final HttpClientContextHandler handler
+ : Lists.reverse(HttpClientSupport.getDynamicContextHandlerList(context))) {
+ try {
+ if (handler != null) {
+ log.trace("Invoking dynamic handler invokeAfter: {}", handler.getClass().getName());
+ handler.invokeAfter(context, request);
+ }
+ } catch (final Throwable t) {
+ log.warn("Dynamic handler invokeAfter threw: {}", handler.getClass().getName(), t);
+ errors.add(t);
+ }
+ }
+
+ for (final HttpClientContextHandler handler : Lists.reverse(handlers)) {
+ try {
+ if (handler != null) {
+ log.trace("Invoking static handler invokeAfter: {}", handler.getClass().getName());
+ handler.invokeAfter(context, request);
+ }
+ } catch (final Throwable t) {
+ log.warn("Static handler invokeAfter threw: {}", handler.getClass().getName(), t);
+ errors.add(t);
+ }
+ }
+
+ final IOException exception = processHandlerErrors("Invoke After", errors);
+ processErrorsForInvokeAfter(exception, priorError);
+
+ }
+
+ /**
+ * Process the error(s) seen during {@link #invokeBefore(HttpUriRequest, HttpClientContext)}
+ * or {@link #invokeAfter(HttpUriRequest, HttpClientContext, IOException, boolean)}
+ * into a single {@link IOException} that will be propagated out of that method.
+ *
+ * @param stage the name of the stage, for reporting purposes
+ * @param errors all errors seen during the method execution
+ *
+ * @return the single exception to be propagated out, will be null if no errors present
+ */
+ private IOException processHandlerErrors(final String stage, final List<Throwable> errors) {
+ if (errors == null || errors.isEmpty()) {
+ return null;
+ }
+
+ if (errors.size() == 1) {
+ final Throwable t = errors.get(0);
+ if (IOException.class.isInstance(t)) {
+ return IOException.class.cast(t);
+ } else {
+ return new IOException(
+ String.format("Context handler threw non-IOException Throwable in stage '%s'", stage), t);
+ }
+ } else {
+ final IOException e = new IOException(
+ String.format("Multiple context handlers in stage '%s' reported error, see suppressed list",
+ stage));
+ for (final Throwable t : errors) {
+ e.addSuppressed(t);
+ }
+ return e;
+ }
+ }
+
+ /**
+ * Process errors for
+ * {@link #invokeAfter(HttpUriRequest, HttpClientContext, Throwable)}.
+ *
+ * @param invokeAfterException the exception thrown by invokeAfter handlers, if any
+ * @param priorError an error thrown by by either {@link #invokeBefore(HttpUriRequest, HttpClientContext)}
+ * or by HttpClient execute(...), if any.
+ *
+ * @throws IOException if invokeAfterException is non-null, or if priorError is an IOException. If priorError
+ * is a type of unchecked error (RuntimeException or Error) that will be propagated out
+ * here as well.
+ */
+ private void processErrorsForInvokeAfter(final IOException invokeAfterException, final Throwable priorError)
+ throws IOException {
+
+ if (priorError != null) {
+ if (invokeAfterException != null) {
+ priorError.addSuppressed(invokeAfterException);
+ }
+ // Note: The RuntimeException and Error cases below can only occur from the HttpClient execute() method,
+ // since a priorError from invokeBefore() is always processed into a checked IOException, and in that case
+ // HttpClient execute() wasn't called at all.
+ if (IOException.class.isInstance(priorError)) {
+ throw IOException.class.cast(priorError);
+ } else if (RuntimeException.class.isInstance(priorError)) {
+ throw RuntimeException.class.cast(priorError);
+ } else if (Error.class.isInstance(priorError)) {
+ throw Error.class.cast(priorError);
+ } else {
+ // This would either be an actual instance of java.lang.Throwable itself (not a subclass),
+ // which really shouldn't ever happen,
+ // or some unaccounted case in a future version of Java which adds additional unchecked base types.
+ // For safety handle by converting to a RuntimeException.
+ throw new RuntimeException(priorError);
+ }
+ } else if (invokeAfterException != null) {
+ throw invokeAfterException;
+ }
+ }
+
+}
diff --git a/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilder.java b/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilder.java
index 3ad6284..6571d6c 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilder.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilder.java
@@ -250,6 +250,9 @@ public class HttpClientBuilder {
/** List of response interceptors to add last. */
@Nonnull @NonnullElements private List<HttpResponseInterceptor> responseInterceptorsLast;
+
+ /** List of static context handlers. */
+ @Nonnull @NonnullElements private List<HttpClientContextHandler> staticContextHandlers;
/** The Apache HttpClientBuilder 4.3+ instance over which to layer this builder. */
private org.apache.http.impl.client.HttpClientBuilder apacheBuilder;
@@ -293,6 +296,7 @@ public class HttpClientBuilder {
requestInterceptorsLast = Collections.emptyList();
responseInterceptorsFirst = Collections.emptyList();
responseInterceptorsLast = Collections.emptyList();
+ staticContextHandlers = Collections.emptyList();
}
/**
@@ -866,7 +870,7 @@ public class HttpClientBuilder {
* @param interceptors the list of interceptors, may be null
*/
public void setFirstRequestInterceptors(@Nullable final List<HttpRequestInterceptor> interceptors) {
- requestInterceptorsFirst = (List<HttpRequestInterceptor>) normalizeInterceptors(interceptors);
+ requestInterceptorsFirst = (List<HttpRequestInterceptor>) normalizeList(interceptors);
}
/**
@@ -885,7 +889,7 @@ public class HttpClientBuilder {
* @param interceptors the list of interceptors, may be null
*/
public void setLastRequestInterceptors(@Nullable final List<HttpRequestInterceptor> interceptors) {
- requestInterceptorsLast = normalizeInterceptors(interceptors);
+ requestInterceptorsLast = normalizeList(interceptors);
}
/**
@@ -904,7 +908,7 @@ public class HttpClientBuilder {
* @param interceptors the list of interceptors, may be null
*/
public void setFirstResponseInterceptors(@Nullable final List<HttpResponseInterceptor> interceptors) {
- responseInterceptorsFirst = normalizeInterceptors(interceptors);
+ responseInterceptorsFirst = normalizeList(interceptors);
}
/**
@@ -923,22 +927,41 @@ public class HttpClientBuilder {
* @param interceptors the list of interceptors, may be null
*/
public void setLastResponseInterceptors(@Nullable final List<HttpResponseInterceptor> interceptors) {
- responseInterceptorsLast = normalizeInterceptors(interceptors);
+ responseInterceptorsLast = normalizeList(interceptors);
+ }
+
+ /**
+ * Get the list of static {@link HttpClientContextHandler}.
+ *
+ * @return the list of handlers
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable
+ public List<HttpClientContextHandler> getStaticContextHandlers() {
+ return ImmutableList.copyOf(staticContextHandlers);
+ }
+
+ /**
+ * Set the list of static {@link HttpClientContextHandler}.
+ *
+ * @param handlers the list of handlers , may be null
+ */
+ public void setStaticContextHandlers(@Nullable final List<HttpClientContextHandler> handlers) {
+ staticContextHandlers = normalizeList(handlers);
}
/**
- * Normalize and copy the supplied list of interceptors to remove nulls.
+ * Normalize and copy the supplied list to remove nulls.
*
* @param <T> type of collection to normalize
*
- * @param interceptors the list of interceptors to normalize
- * @return copy of input list without nulls, may be null
+ * @param items the list of items to normalize
+ * @return copy of input list without nulls
*/
- @Nonnull @NonnullElements private <T> List<T> normalizeInterceptors(@Nullable final List<T> interceptors) {
- if (interceptors == null) {
+ @Nonnull @NonnullElements private <T> List<T> normalizeList(@Nullable final List<T> items) {
+ if (items == null) {
return Collections.emptyList();
} else {
- return new ArrayList<>(Collections2.filter(interceptors, Predicates.notNull()));
+ return new ArrayList<>(Collections2.filter(items, Predicates.notNull()));
}
}
@@ -951,7 +974,7 @@ public class HttpClientBuilder {
*/
public HttpClient buildClient() throws Exception {
decorateApacheBuilder();
- return getApacheBuilder().build();
+ return new ContextHandlingHttpClient(getApacheBuilder().build(), getStaticContextHandlers());
}
/**
diff --git a/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupport.java b/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupport.java
index 552135e..2d4c63b 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupport.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupport.java
@@ -28,7 +28,9 @@ import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -38,6 +40,7 @@ import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
@@ -49,6 +52,7 @@ import org.apache.http.util.CharArrayBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.DeprecationSupport;
import net.shibboleth.utilities.java.support.primitive.DeprecationSupport.ObjectType;
@@ -57,6 +61,11 @@ import net.shibboleth.utilities.java.support.primitive.DeprecationSupport.Object
*/
public final class HttpClientSupport {
+ /** Context key for instances of dynamic context handlers to be invoked before and after the HTTP request.
+ * Must be an instance of
+ * {@link java.util.List}<code><</code>{@link HttpClientContextHandler}<code>></code>. */
+ private static final String CONTEXT_KEY_DYNAMIC_CONTEXT_HANDLERS = "java-support.DynamicContextHandlers";
+
/** Constructor to prevent instantiation. */
private HttpClientSupport() { }
@@ -175,6 +184,50 @@ public final class HttpClientSupport {
}
+ /**
+ * Get the list of {@link HttpClientContextHandler} for the {@link HttpClientContext}.
+ *
+ * @param context the client context
+ * @return the handler list
+ */
+ @Nonnull public static List<HttpClientContextHandler> getDynamicContextHandlerList(
+ @Nonnull final HttpClientContext context) {
+ Constraint.isNotNull(context, "HttpClientContext was null");
+ List<HttpClientContextHandler> handlers =
+ context.getAttribute(CONTEXT_KEY_DYNAMIC_CONTEXT_HANDLERS, List.class);
+ if (handlers == null) {
+ handlers = new ArrayList<>();
+ context.setAttribute(CONTEXT_KEY_DYNAMIC_CONTEXT_HANDLERS, handlers);
+ }
+ return handlers;
+ }
+
+ /**
+ * Add the specified instance of {@link HttpClientContextHandler}
+ * to the {@link HttpClientContext} in the first handler list position.
+ *
+ * @param context the client context
+ * @param handler the handler to add
+ */
+ public static void addDynamicContextHandlerFirst(@Nonnull final HttpClientContext context,
+ @Nonnull final HttpClientContextHandler handler) {
+ Constraint.isNotNull(handler, "HttpClientContextHandler was null");
+ getDynamicContextHandlerList(context).add(0, handler);
+ }
+
+ /**
+ * Add the specified instance of {@link HttpClientContextHandler}
+ * to the {@link HttpClientContext} in the last handler list position.
+ *
+ * @param context the client context
+ * @param handler the handler to add
+ */
+ public static void addDynamicContextHandlerLast(@Nonnull final HttpClientContext context,
+ @Nonnull final HttpClientContextHandler handler) {
+ Constraint.isNotNull(handler, "HttpClientContextHandler was null");
+ getDynamicContextHandlerList(context).add(handler);
+ }
+
// Checkstyle: CyclomaticComplexity OFF
/**
* Get the entity content as a String, using the provided default character set
diff --git a/src/test/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClientTest.java b/src/test/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClientTest.java
new file mode 100644
index 0000000..1936ce8
--- /dev/null
+++ b/src/test/java/net/shibboleth/utilities/java/support/httpclient/ContextHandlingHttpClientTest.java
@@ -0,0 +1,1962 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+package net.shibboleth.utilities.java.support.httpclient;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Lists;
+
+public class ContextHandlingHttpClientTest {
+
+ private ContextHandlingHttpClient client;
+
+ private TestContextHandler staticOne, staticTwo, staticThree;
+ private TestContextHandler dynamicOne, dynamicTwo, dynamicThree;
+
+ private HttpClientContext context;
+
+ private HttpUriRequest request;
+ private HttpHost target;
+ private ResponseHandler<Object> responseHandler = new MockResponseHandler();
+
+ @BeforeClass
+ public void setupClass() {
+ staticOne = new TestContextHandler("static-1");
+ staticTwo = new TestContextHandler("static-2");
+ staticThree = new TestContextHandler("static-3");
+ dynamicOne = new TestContextHandler("dynamic-1");
+ dynamicTwo = new TestContextHandler("dynamic-2");
+ dynamicThree = new TestContextHandler("dynamic-3");
+
+ }
+
+ @BeforeMethod
+ public void setupMethod() {
+ request = new HttpGet("/test");
+ target = new HttpHost("test.example.edu");
+ }
+
+ @Test
+ public void testNoHandlers() throws ClientProtocolException, IOException {
+ client = new ContextHandlingHttpClient(new MockHttpClient());
+ context = HttpClientContext.create();
+
+ //Non-context execute methods
+ Assert.assertSame(client.execute(request), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertSame(client.execute(request, responseHandler), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertSame(client.execute(target, request), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertSame(client.execute(target, request, responseHandler), MockHttpClient.STATIC_RESPONSE_HANDLER);
+
+ //Context execute methods
+ Assert.assertSame(client.execute(request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertSame(client.execute(request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertSame(client.execute(target, request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertSame(client.execute(target, request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ }
+
+ @Test
+ public void testStaticOnly() throws ClientProtocolException, IOException {
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ context = HttpClientContext.create();
+ Assert.assertSame(client.execute(request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ Assert.assertSame(client.execute(request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ Assert.assertSame(client.execute(target, request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ Assert.assertSame(client.execute(target, request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ @Test
+ public void testDynamicOnly() throws ClientProtocolException, IOException {
+ client = new ContextHandlingHttpClient(new MockHttpClient());
+
+ List<String> control = Lists.newArrayList(
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(target, request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(target, request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ @Test
+ public void testStaticAndDynamic() throws ClientProtocolException, IOException {
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(target, request, context), MockHttpClient.STATIC_RESPONSE_HTTP);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ Assert.assertSame(client.execute(target, request, responseHandler, context), MockHttpClient.STATIC_RESPONSE_HANDLER);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ @Test
+ public void testWrappedClientThrowsIOException() throws ClientProtocolException, IOException {
+ IOException error = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(error), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testWrappedClientThrowsRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(error), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (RuntimeException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (RuntimeException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (RuntimeException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (RuntimeException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testWrappedClientThrowsError() throws ClientProtocolException, IOException {
+ Error error = new Error();
+ client = new ContextHandlingHttpClient(new MockHttpClient(error), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (Error e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (Error e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (Error e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (Error e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleStaticHandlerInvokeBeforeThrowsIOException() throws ClientProtocolException, IOException {
+ IOException error = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", error, null), staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleStaticHandlerInvokeAfterThrowsIOException() throws ClientProtocolException, IOException {
+ IOException error = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", null, error), staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleStaticHandlerInvokeBeforeThrowsRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", error, null), staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleStaticHandlerInvokeAfterThrowsRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", null, error), staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleStaticHandlersInvokeBeforeThrowIOException() throws ClientProtocolException, IOException {
+ IOException error1 = new IOException();
+ IOException error3 = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList( new TestContextHandler("static-1", error1, null), staticTwo, new TestContextHandler("static-3", error3, null)));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleStaticHandlersInvokeBeforeThrowRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error1 = new RuntimeException();
+ RuntimeException error3 = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList( new TestContextHandler("static-1", error1, null), staticTwo, new TestContextHandler("static-3", error3, null)));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+ @Test
+ public void testMultipleStaticHandlersInvokeAfterThrowIOException() throws ClientProtocolException, IOException {
+ IOException error1 = new IOException();
+ IOException error3 = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList( new TestContextHandler("static-1", null, error1), staticTwo, new TestContextHandler("static-3", null, error3)));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleStaticHandlersInvokeAfterThrowRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error1 = new RuntimeException();
+ RuntimeException error3 = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList( new TestContextHandler("static-1", null, error1), staticTwo, new TestContextHandler("static-3", null, error3)));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, dynamicTwo, dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+ @Test
+ public void testSingleDynamicHandlerInvokeBeforeThrowsIOException() throws ClientProtocolException, IOException {
+ IOException error = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", error, null), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleDynamicHandlerInvokeAfterThrowsIOException() throws ClientProtocolException, IOException {
+ IOException error = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, error), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+ @Test
+ public void testSingleDynamicHandlerInvokeBeforeThrowsRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", error, null), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testSingleDynamicHandlerInvokeAfterThrowsRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, error), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), error);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+ @Test
+ public void testMultipleDynamicHandlersInvokeBeforeThrowIOException() throws ClientProtocolException, IOException {
+ IOException error1 = new IOException();
+ IOException error3 = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers =
+ Lists.newArrayList(new TestContextHandler("dynamic-1", error1, null), dynamicTwo, new TestContextHandler("dynamic-3", error3, null));
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleDynamicHandlersInvokeBeforeThrowRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error1 = new RuntimeException();
+ RuntimeException error3 = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers =
+ Lists.newArrayList(new TestContextHandler("dynamic-1", error1, null), dynamicTwo, new TestContextHandler("dynamic-3", error3, null));
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleDynamicHandlersInvokeAfterThrowIOException() throws ClientProtocolException, IOException {
+ IOException error1 = new IOException();
+ IOException error3 = new IOException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers =
+ Lists.newArrayList(new TestContextHandler("dynamic-1", null, error1), dynamicTwo, new TestContextHandler("dynamic-3", null, error3));
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testMultipleDynamicHandlersInvokeAfterThrowRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException error1 = new RuntimeException();
+ RuntimeException error3 = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(), Lists.newArrayList(staticOne, staticTwo, staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers =
+ Lists.newArrayList(new TestContextHandler("dynamic-1", null, error1), dynamicTwo, new TestContextHandler("dynamic-3", null, error3));
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertNotSame(e, error1);
+ Assert.assertNotSame(e, error3);
+ Assert.assertEquals(e.getSuppressed().length, 2);
+ Assert.assertTrue(Arrays.asList(e.getSuppressed()).containsAll(Lists.newArrayList(error1, error3)));
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+ @Test
+ public void testStaticAndDynamicHandlersThrowIOException() throws ClientProtocolException, IOException {
+ IOException staticBeforeError = null;
+ IOException dynamicAfterError = null;
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> dynamicHandlers = null;
+
+ staticBeforeError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", staticBeforeError, null), staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ staticBeforeError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", staticBeforeError, null), staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ staticBeforeError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", staticBeforeError, null), staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ staticBeforeError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", staticBeforeError, null), staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testStaticAndDynamicHandlersThrowRuntimeException() throws ClientProtocolException, IOException {
+ RuntimeException staticBeforeError = new RuntimeException();
+ RuntimeException dynamicAfterError = new RuntimeException();
+ client = new ContextHandlingHttpClient(new MockHttpClient(),
+ Lists.newArrayList(staticOne, new TestContextHandler("static-2", staticBeforeError, null), staticThree));
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> handlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0].getCause(), dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0].getCause(), dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0].getCause(), dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(handlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e.getCause(), staticBeforeError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0].getCause(), dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+ @Test
+ public void testWrappedClientThrowsIOExceptionInvokeAfterThrowsIOException() throws ClientProtocolException, IOException {
+ IOException clientError = null;
+ IOException dynamicAfterError = null;
+
+ List<String> control = Lists.newArrayList(
+ "before-static-1",
+ "before-static-2",
+ "before-static-3",
+ "before-dynamic-1",
+ "before-dynamic-2",
+ "before-dynamic-3",
+ "after-dynamic-3",
+ "after-dynamic-2",
+ "after-dynamic-1",
+ "after-static-3",
+ "after-static-2",
+ "after-static-1"
+ );
+
+ List<HttpClientContextHandler> dynamicHandlers = null;
+
+ clientError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(clientError),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, clientError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ clientError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(clientError),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, clientError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ clientError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(clientError),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(target, request, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, clientError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+
+ clientError = new IOException();
+ dynamicAfterError = new IOException();
+
+ client = new ContextHandlingHttpClient(new MockHttpClient(clientError),
+ Lists.newArrayList(staticOne, staticTwo, staticThree));
+ dynamicHandlers = Lists.newArrayList(dynamicOne, new TestContextHandler("dynamic-2", null, dynamicAfterError), dynamicThree);
+
+ try {
+ context = HttpClientContext.create();
+ HttpClientSupport.getDynamicContextHandlerList(context).addAll(dynamicHandlers);
+ client.execute(target, request, responseHandler, context);
+ Assert.fail("Wrapped client should have thrown");
+ } catch (IOException e) {
+ Assert.assertSame(e, clientError);
+ Assert.assertEquals(e.getSuppressed().length, 1);
+ Assert.assertSame(e.getSuppressed()[0], dynamicAfterError);
+ Assert.assertEquals(context.getAttribute(TestContextHandler.TEST_KEY), control);
+ }
+ }
+
+
+
+
+
+ // Helpers
+
+ private class TestContextHandler implements HttpClientContextHandler {
+
+ public static final String TEST_KEY = "testKey";
+
+ private String name;
+
+ private Throwable invokeBeforeError;
+ private Throwable invokeAfterError;
+
+ public TestContextHandler(String instanceName) {
+ name = instanceName;
+ }
+
+ public TestContextHandler(Throwable beforeError, Throwable afterError) {
+ invokeBeforeError = beforeError;
+ invokeAfterError = afterError;
+ }
+
+ public TestContextHandler(String instanceName, Throwable beforeError, Throwable afterError) {
+ name = instanceName;
+ invokeBeforeError = beforeError;
+ invokeAfterError = afterError;
+ }
+
+ /** {@inheritDoc} */
+ public void invokeBefore(HttpClientContext context, HttpUriRequest request) throws IOException {
+ if (name != null) {
+ addValue(context, "before-" + name);
+ }
+ ThrowableHelper.checkAndThrowError(invokeBeforeError);
+ }
+
+ /** {@inheritDoc} */
+ public void invokeAfter(HttpClientContext context, HttpUriRequest request) throws IOException {
+ if (name != null) {
+ addValue(context, "after-" + name);
+ }
+ ThrowableHelper.checkAndThrowError(invokeAfterError);
+ }
+
+ private void addValue(HttpClientContext context, String value) {
+ List<String> attrib = context.getAttribute(TEST_KEY, List.class);
+ if (attrib == null) {
+ attrib = new ArrayList<>();
+ context.setAttribute(TEST_KEY, attrib);
+ }
+ attrib.add(value);
+ }
+
+ }
+
+ private static class MockHttpClient implements HttpClient {
+
+ public static final HttpResponse STATIC_RESPONSE_HTTP = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
+
+ public static final Object STATIC_RESPONSE_HANDLER = new Object();
+
+ private Throwable error;
+
+ public MockHttpClient() {
+ }
+
+ public MockHttpClient(final Throwable throwable) {
+ error = throwable;
+ }
+
+ /** {@inheritDoc} */
+ public HttpParams getParams() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public ClientConnectionManager getConnectionManager() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
+ return responseHTTP();
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(HttpUriRequest request, HttpContext context)
+ throws IOException, ClientProtocolException {
+ return responseHTTP();
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
+ return responseHTTP();
+ }
+
+ /** {@inheritDoc} */
+ public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)
+ throws IOException, ClientProtocolException {
+ return responseHTTP();
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
+ return responseHandler();
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context)
+ throws IOException, ClientProtocolException {
+ return responseHandler();
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
+ return responseHandler();
+ }
+
+ /** {@inheritDoc} */
+ public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler,
+ HttpContext context) throws IOException, ClientProtocolException {
+ return responseHandler();
+ }
+
+ private HttpResponse responseHTTP() throws IOException {
+ ThrowableHelper.checkAndThrowError(error);
+ return STATIC_RESPONSE_HTTP;
+ }
+
+ private <T> T responseHandler() throws IOException {
+ ThrowableHelper.checkAndThrowError(error);
+ return (T) STATIC_RESPONSE_HANDLER;
+ }
+
+ }
+
+ public static class MockResponseHandler implements ResponseHandler<Object> {
+
+ public Object handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ return null;
+ }
+
+ }
+
+ public static class ThrowableHelper {
+
+ public static void checkAndThrowError(Throwable t) throws IOException {
+ if (t != null) {
+ if (IOException.class.isInstance(t)) {
+ throw IOException.class.cast(t);
+ }
+ if (RuntimeException.class.isInstance(t)) {
+ throw RuntimeException.class.cast(t);
+ }
+ if (Error.class.isInstance(t)) {
+ throw Error.class.cast(t);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilderTest.java b/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilderTest.java
index 3cf0409..d8d0369 100644
--- a/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilderTest.java
+++ b/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientBuilderTest.java
@@ -18,12 +18,17 @@
package net.shibboleth.utilities.java.support.httpclient;
+import java.io.IOException;
import java.time.Duration;
import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
import org.testng.Assert;
import org.testng.annotations.Test;
+import com.google.common.collect.Lists;
+
import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
public class HttpClientBuilderTest {
@@ -49,4 +54,54 @@ public class HttpClientBuilderTest {
Assert.assertNotNull(client);
}
+ @Test
+ public void testContextHandlingSupport() throws Exception {
+
+ HttpClientContextHandler handler1 = new TestContextHandler();
+ HttpClientContextHandler handler2 = new TestContextHandler();
+ HttpClientContextHandler handler3 = new TestContextHandler();
+
+ final HttpClientBuilder builder = new HttpClientBuilder();
+
+ Assert.assertNotNull(builder.getStaticContextHandlers());
+ Assert.assertTrue(builder.getStaticContextHandlers().isEmpty());
+
+ builder.setStaticContextHandlers(Lists.newArrayList(null, handler1, null, handler2, null, handler3));
+ Assert.assertEquals(builder.getStaticContextHandlers(), Lists.newArrayList(handler1, handler2, handler3));
+
+ try {
+ builder.getStaticContextHandlers().add(new TestContextHandler());
+ Assert.fail("List should have been unmodifaible");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+
+ builder.resetDefaults();
+
+ Assert.assertNotNull(builder.getStaticContextHandlers());
+ Assert.assertTrue(builder.getStaticContextHandlers().isEmpty());
+
+ final HttpClient client = builder.buildClient();
+ Assert.assertNotNull(client);
+ Assert.assertTrue(ContextHandlingHttpClient.class.isInstance(client));
+
+ }
+
+ //Helpers
+
+ public class TestContextHandler implements HttpClientContextHandler {
+
+ /** {@inheritDoc} */
+ public void invokeBefore(HttpClientContext context, HttpUriRequest request) throws IOException {
+
+ }
+
+ /** {@inheritDoc} */
+ public void invokeAfter(HttpClientContext context, HttpUriRequest request) throws IOException {
+
+ }
+
+ }
+
+
}
diff --git a/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupportTest.java b/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupportTest.java
new file mode 100644
index 0000000..4eb37ee
--- /dev/null
+++ b/src/test/java/net/shibboleth/utilities/java/support/httpclient/HttpClientSupportTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+package net.shibboleth.utilities.java.support.httpclient;
+
+import java.io.IOException;
+
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Lists;
+
+public class HttpClientSupportTest {
+
+ @Test
+ public void testAddDynamicContextHandlerFirst() {
+ HttpClientContext context = HttpClientContext.create();
+ HttpClientContextHandler one = new TestContextHandler();
+ HttpClientContextHandler two = new TestContextHandler();
+ HttpClientContextHandler three = new TestContextHandler();
+
+ HttpClientSupport.addDynamicContextHandlerFirst(context, one);
+ HttpClientSupport.addDynamicContextHandlerFirst(context, two);
+ HttpClientSupport.addDynamicContextHandlerFirst(context, three);
+
+ Assert.assertEquals(HttpClientSupport.getDynamicContextHandlerList(context), Lists.newArrayList(three, two, one));
+ }
+
+ @Test
+ public void testAddDynamicContextHandlerLast() {
+ HttpClientContext context = HttpClientContext.create();
+ HttpClientContextHandler one = new TestContextHandler();
+ HttpClientContextHandler two = new TestContextHandler();
+ HttpClientContextHandler three = new TestContextHandler();
+
+ HttpClientSupport.addDynamicContextHandlerLast(context, one);
+ HttpClientSupport.addDynamicContextHandlerLast(context, two);
+ HttpClientSupport.addDynamicContextHandlerLast(context, three);
+
+ Assert.assertEquals(HttpClientSupport.getDynamicContextHandlerList(context), Lists.newArrayList(one, two, three));
+ }
+
+
+ //Helpers
+
+ public class TestContextHandler implements HttpClientContextHandler {
+
+ /** {@inheritDoc} */
+ public void invokeBefore(HttpClientContext context, HttpUriRequest request) throws IOException {
+
+ }
+
+ /** {@inheritDoc} */
+ public void invokeAfter(HttpClientContext context, HttpUriRequest request) throws IOException {
+
+ }
+
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list