You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/09/02 15:28:04 UTC
[04/17] httpcomponents-client git commit: Moved classes and renamed
packages (no functional changes)
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
new file mode 100644
index 0000000..10313d1
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
@@ -0,0 +1,348 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.UserTokenHandler;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.impl.ConnectionShutdownException;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ConnectionReuseStrategy;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.util.TimeValue;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestMainClientExec {
+
+ @Mock
+ private ConnectionReuseStrategy reuseStrategy;
+ @Mock
+ private ConnectionKeepAliveStrategy keepAliveStrategy;
+ @Mock
+ private UserTokenHandler userTokenHandler;
+ @Mock
+ private ExecRuntime endpoint;
+
+ private MainClientExec mainClientExec;
+ private HttpHost target;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mainClientExec = new MainClientExec(reuseStrategy, keepAliveStrategy, userTokenHandler);
+ target = new HttpHost("foo", 80);
+ }
+
+ @Test
+ public void testExecRequestNonPersistentConnection() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ response.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+
+ Mockito.when(endpoint.isConnectionAcquired()).thenReturn(false);
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(false);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
+ Mockito.verify(endpoint).execute(request, context);
+ Mockito.verify(endpoint, Mockito.times(1)).markConnectionNonReusable();
+ Mockito.verify(endpoint, Mockito.never()).releaseConnection();
+
+ Assert.assertNull(context.getUserToken());
+ Assert.assertNotNull(finalResponse);
+ Assert.assertTrue(finalResponse instanceof CloseableHttpResponse);
+ }
+
+ @Test
+ public void testExecRequestNonPersistentConnectionNoResponseEntity() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ response.setEntity(null);
+
+ Mockito.when(endpoint.isConnectionAcquired()).thenReturn(false);
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(false);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
+
+ Mockito.verify(endpoint).execute(request, context);
+ Mockito.verify(endpoint).markConnectionNonReusable();
+ Mockito.verify(endpoint).releaseConnection();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertTrue(finalResponse instanceof CloseableHttpResponse);
+ }
+
+ @Test
+ public void testExecRequestPersistentConnection() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ // The entity is streaming
+ response.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(true);
+ Mockito.when(keepAliveStrategy.getKeepAliveDuration(
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(TimeValue.ofMillis(678L));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
+
+ Mockito.verify(endpoint).execute(request, context);
+ Mockito.verify(endpoint).markConnectionReusable();
+ Mockito.verify(endpoint, Mockito.never()).releaseConnection();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertTrue(finalResponse instanceof CloseableHttpResponse);
+ }
+
+ @Test
+ public void testExecRequestPersistentConnectionNoResponseEntity() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(true);
+ Mockito.when(keepAliveStrategy.getKeepAliveDuration(
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(TimeValue.ofMillis(678L));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
+
+ Mockito.verify(endpoint).execute(request, context);
+ Mockito.verify(endpoint).releaseConnection();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertTrue(finalResponse instanceof CloseableHttpResponse);
+ }
+
+ @Test
+ public void testExecRequestConnectionRelease() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ // The entity is streaming
+ response.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
+ Mockito.verify(endpoint, Mockito.times(1)).execute(request, context);
+ Mockito.verify(endpoint, Mockito.never()).disconnect();
+ Mockito.verify(endpoint, Mockito.never()).releaseConnection();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertTrue(finalResponse instanceof CloseableHttpResponse);
+ finalResponse.close();
+
+ Mockito.verify(endpoint).disconnect();
+ Mockito.verify(endpoint).discardConnection();
+ }
+
+ @Test(expected=InterruptedIOException.class)
+ public void testExecConnectionShutDown() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenThrow(new ConnectionShutdownException());
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ mainClientExec.execute(request, scope, null);
+ } catch (Exception ex) {
+ Mockito.verify(endpoint).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void testExecRuntimeException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenThrow(new RuntimeException("Ka-boom"));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ mainClientExec.execute(request, scope, null);
+ } catch (final Exception ex) {
+ Mockito.verify(endpoint).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test(expected=HttpException.class)
+ public void testExecHttpException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenThrow(new HttpException("Ka-boom"));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ mainClientExec.execute(request, scope, null);
+ } catch (final Exception ex) {
+ Mockito.verify(endpoint).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test(expected=IOException.class)
+ public void testExecIOException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ Mockito.when(endpoint.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenThrow(new IOException("Ka-boom"));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ mainClientExec.execute(request, scope, null);
+ } catch (final Exception ex) {
+ Mockito.verify(endpoint).discardConnection();
+ throw ex;
+ }
+ }
+
+ static class ConnectionState {
+
+ private boolean connected;
+
+ public Answer connectAnswer() {
+
+ return new Answer() {
+
+ @Override
+ public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ connected = true;
+ return null;
+ }
+
+ };
+ }
+
+ public Answer<Boolean> isConnectedAnswer() {
+
+ return new Answer<Boolean>() {
+
+ @Override
+ public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ return connected;
+ }
+
+ };
+
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestNullBackoffStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestNullBackoffStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestNullBackoffStrategy.java
new file mode 100644
index 0000000..9c7411a
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestNullBackoffStrategy.java
@@ -0,0 +1,57 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import static org.junit.Assert.assertFalse;
+
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class TestNullBackoffStrategy {
+
+ private NullBackoffStrategy impl;
+
+ @Before
+ public void setUp() {
+ impl = new NullBackoffStrategy();
+ }
+
+ @Test
+ public void doesNotBackoffForThrowables() {
+ assertFalse(impl.shouldBackoff(new Exception()));
+ }
+
+ @Test
+ public void doesNotBackoffForResponses() {
+ final HttpResponse resp = new BasicHttpResponse(HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable");
+ assertFalse(impl.shouldBackoff(resp));
+ }
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
new file mode 100644
index 0000000..881af34
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
@@ -0,0 +1,341 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.hc.client5.http.AuthenticationStrategy;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.NonRepeatableRequestException;
+import org.apache.hc.client5.http.auth.AuthChallenge;
+import org.apache.hc.client5.http.auth.AuthExchange;
+import org.apache.hc.client5.http.auth.AuthScheme;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.ChallengeType;
+import org.apache.hc.client5.http.auth.Credentials;
+import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.auth.NTLMScheme;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SuppressWarnings({"static-access"}) // test code
+public class TestProtocolExec {
+
+ @Mock
+ private HttpProcessor httpProcessor;
+ @Mock
+ private AuthenticationStrategy targetAuthStrategy;
+ @Mock
+ private AuthenticationStrategy proxyAuthStrategy;
+ @Mock
+ private ExecChain chain;
+ @Mock
+ private ExecRuntime execRuntime;
+
+ private ProtocolExec protocolExec;
+ private HttpHost target;
+ private HttpHost proxy;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ protocolExec = new ProtocolExec(httpProcessor, targetAuthStrategy, proxyAuthStrategy);
+ target = new HttpHost("foo", 80);
+ proxy = new HttpHost("bar", 8888);
+ }
+
+ @Test
+ public void testFundamentals() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final ClassicHttpRequest request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ protocolExec.execute(request, scope, chain);
+
+ Mockito.verify(httpProcessor).process(request, null, context);
+ Mockito.verify(chain).proceed(request, scope);
+ Mockito.verify(httpProcessor).process(response, null, context);
+
+ Assert.assertEquals(route, context.getHttpRoute());
+ Assert.assertSame(request, context.getRequest());
+ Assert.assertSame(response, context.getResponse());
+ }
+
+ @Test
+ public void testUserInfoInRequestURI() throws Exception {
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 8080));
+ final ClassicHttpRequest request = new HttpGet("http://somefella:secret@bar/test");
+ final HttpClientContext context = HttpClientContext.create();
+ context.setCredentialsProvider(new BasicCredentialsProvider());
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ protocolExec.execute(request, scope, chain);
+ Assert.assertEquals(new URI("http://bar/test"), request.getUri());
+ final CredentialsProvider credentialsProvider = context.getCredentialsProvider();
+ final Credentials creds = credentialsProvider.getCredentials(new AuthScope("bar", -1, null), null);
+ Assert.assertNotNull(creds);
+ Assert.assertEquals("somefella", creds.getUserPrincipal().getName());
+ }
+
+ @Test(expected = HttpException.class)
+ public void testPostProcessHttpException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final ClassicHttpRequest request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.doThrow(new HttpException("Ooopsie")).when(httpProcessor).process(
+ Mockito.same(response), Mockito.<EntityDetails>isNull(), Mockito.<HttpContext>any());
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ try {
+ protocolExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(execRuntime).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test(expected = IOException.class)
+ public void testPostProcessIOException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final ClassicHttpRequest request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.doThrow(new IOException("Ooopsie")).when(httpProcessor).process(
+ Mockito.same(response), Mockito.<EntityDetails>isNull(), Mockito.<HttpContext>any());
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ try {
+ protocolExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(execRuntime).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testPostProcessRuntimeException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final ClassicHttpRequest request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.doThrow(new RuntimeException("Ooopsie")).when(httpProcessor).process(
+ Mockito.same(response), Mockito.<EntityDetails>isNull(), Mockito.<HttpContext>any());
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ try {
+ protocolExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(execRuntime).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test
+ public void testExecRequestRetryOnAuthChallenge() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://foo/test");
+ final ClassicHttpResponse response1 = new BasicClassicHttpResponse(401, "Huh?");
+ response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ response1.setEntity(EntityBuilder.create()
+ .setStream(instream1)
+ .build());
+ final ClassicHttpResponse response2 = new BasicClassicHttpResponse(200, "OK");
+ final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {2, 3, 4}));
+ response2.setEntity(EntityBuilder.create()
+ .setStream(instream2)
+ .build());
+
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user", "pass".toCharArray()));
+ context.setCredentialsProvider(credentialsProvider);
+
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1, response2);
+ Mockito.when(targetAuthStrategy.select(
+ Mockito.eq(ChallengeType.TARGET),
+ Mockito.<Map<String, AuthChallenge>>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ final ClassicHttpResponse finalResponse = protocolExec.execute(request, scope, chain);
+ Mockito.verify(chain, Mockito.times(2)).proceed(request, scope);
+ Mockito.verify(instream1).close();
+ Mockito.verify(instream2, Mockito.never()).close();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertEquals(200, finalResponse.getCode());
+ }
+
+ @Test
+ public void testExecEntityEnclosingRequestRetryOnAuthChallenge() throws Exception {
+ final HttpRoute route = new HttpRoute(target, proxy);
+ final ClassicHttpRequest request = new HttpGet("http://foo/test");
+ final ClassicHttpResponse response1 = new BasicClassicHttpResponse(401, "Huh?");
+ response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ response1.setEntity(EntityBuilder.create()
+ .setStream(instream1)
+ .build());
+ final ClassicHttpResponse response2 = new BasicClassicHttpResponse(200, "OK");
+ final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {2, 3, 4}));
+ response2.setEntity(EntityBuilder.create()
+ .setStream(instream2)
+ .build());
+
+ final HttpClientContext context = new HttpClientContext();
+
+ final AuthExchange proxyAuthExchange = new AuthExchange();
+ proxyAuthExchange.setState(AuthExchange.State.SUCCESS);
+ proxyAuthExchange.select(new NTLMScheme());
+ context.setAuthExchange(proxy, proxyAuthExchange);
+
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user", "pass".toCharArray()));
+ context.setCredentialsProvider(credentialsProvider);
+
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1, response2);
+
+ Mockito.when(targetAuthStrategy.select(
+ Mockito.eq(ChallengeType.TARGET),
+ Mockito.<Map<String, AuthChallenge>>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ final ClassicHttpResponse finalResponse = protocolExec.execute(request, scope, chain);
+ Mockito.verify(chain, Mockito.times(2)).proceed(request, scope);
+ Mockito.verify(execRuntime).disconnect();
+ Mockito.verify(instream2, Mockito.never()).close();
+
+ Assert.assertNotNull(finalResponse);
+ Assert.assertEquals(200, finalResponse.getCode());
+ Assert.assertNull(proxyAuthExchange.getAuthScheme());
+ }
+
+ @Test(expected = NonRepeatableRequestException.class)
+ public void testExecEntityEnclosingRequest() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final HttpPost request = new HttpPost("http://foo/test");
+ final InputStream instream0 = new ByteArrayInputStream(new byte[] {1, 2, 3});
+ request.setEntity(EntityBuilder.create()
+ .setStream(instream0)
+ .build());
+ final ClassicHttpResponse response1 = new BasicClassicHttpResponse(401, "Huh?");
+ response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
+ final InputStream instream1 = new ByteArrayInputStream(new byte[] {1, 2, 3});
+ response1.setEntity(EntityBuilder.create()
+ .setStream(instream1)
+ .build());
+
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user", "pass".toCharArray()));
+ context.setCredentialsProvider(credentialsProvider);
+
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<HttpResponse>() {
+
+ @Override
+ public HttpResponse answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ final Object[] args = invocationOnMock.getArguments();
+ final ClassicHttpRequest requestEE = (ClassicHttpRequest) args[0];
+ requestEE.getEntity().writeTo(new ByteArrayOutputStream());
+ return response1;
+ }
+
+ });
+
+ Mockito.when(targetAuthStrategy.select(
+ Mockito.eq(ChallengeType.TARGET),
+ Mockito.<Map<String, AuthChallenge>>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ protocolExec.execute(request, scope, chain);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRedirectExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRedirectExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRedirectExec.java
new file mode 100644
index 0000000..0346ead
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRedirectExec.java
@@ -0,0 +1,350 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.RedirectException;
+import org.apache.hc.client5.http.auth.AuthExchange;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.auth.NTLMScheme;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.protocol.RedirectStrategy;
+import org.apache.hc.client5.http.routing.HttpRoutePlanner;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.ProtocolException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestRedirectExec {
+
+ @Mock
+ private HttpRoutePlanner httpRoutePlanner;
+ @Mock
+ private RedirectStrategy redirectStrategy;
+ @Mock
+ private ExecChain chain;
+ @Mock
+ private ExecRuntime endpoint;
+
+ private RedirectExec redirectExec;
+ private HttpHost target;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ redirectExec = new RedirectExec(httpRoutePlanner, redirectStrategy);
+ target = new HttpHost("localhost", 80);
+ }
+
+ @Test
+ public void testFundamentals() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ final HttpEntity entity1 = EntityBuilder.create()
+ .setStream(instream1)
+ .build();
+ Mockito.when(response1.getEntity()).thenReturn(entity1);
+ final ClassicHttpResponse response2 = Mockito.mock(ClassicHttpResponse.class);
+ final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ final HttpEntity entity2 = EntityBuilder.create()
+ .setStream(instream2)
+ .build();
+ Mockito.when(response2.getEntity()).thenReturn(entity2);
+ final URI redirect = new URI("http://localhost:80/redirect");
+
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(chain.proceed(
+ HttpRequestMatcher.matchesRequestUri(redirect),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response2);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.when(redirectStrategy.getLocationURI(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(redirect);
+ Mockito.when(httpRoutePlanner.determineRoute(
+ Mockito.eq(target),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ redirectExec.execute(request, scope, chain);
+
+ final ArgumentCaptor<ClassicHttpRequest> reqCaptor = ArgumentCaptor.forClass(
+ ClassicHttpRequest.class);
+ Mockito.verify(chain, Mockito.times(2)).proceed(
+ reqCaptor.capture(),
+ Mockito.same(scope));
+
+ final List<ClassicHttpRequest> allValues = reqCaptor.getAllValues();
+ Assert.assertNotNull(allValues);
+ Assert.assertEquals(2, allValues.size());
+ Assert.assertSame(request, allValues.get(0));
+
+ Mockito.verify(response1, Mockito.times(1)).close();
+ Mockito.verify(instream1, Mockito.times(1)).close();
+ Mockito.verify(response2, Mockito.never()).close();
+ Mockito.verify(instream2, Mockito.never()).close();
+ }
+
+ @Test(expected = RedirectException.class)
+ public void testMaxRedirect() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+ final RequestConfig config = RequestConfig.custom()
+ .setRedirectsEnabled(true)
+ .setMaxRedirects(3)
+ .build();
+ context.setRequestConfig(config);
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ final URI redirect = new URI("http://localhost:80/redirect");
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpResponse>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.when(redirectStrategy.getLocationURI(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpResponse>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(redirect);
+ Mockito.when(httpRoutePlanner.determineRoute(
+ Mockito.eq(target),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ redirectExec.execute(request, scope, chain);
+ }
+
+ @Test(expected = HttpException.class)
+ public void testRelativeRedirect() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ final ClassicHttpResponse response2 = Mockito.mock(ClassicHttpResponse.class);
+ final URI redirect = new URI("/redirect");
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(chain.proceed(
+ HttpRequestMatcher.matchesRequestUri(redirect),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response2);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.when(redirectStrategy.getLocationURI(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(redirect);
+ Mockito.when(httpRoutePlanner.determineRoute(
+ Mockito.eq(target),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ redirectExec.execute(request, scope, chain);
+ }
+
+ @Test
+ public void testCrossSiteRedirect() throws Exception {
+
+ final HttpHost proxy = new HttpHost("proxy");
+ final HttpRoute route = new HttpRoute(target, proxy);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final AuthExchange targetAuthExchange = new AuthExchange();
+ targetAuthExchange.setState(AuthExchange.State.SUCCESS);
+ targetAuthExchange.select(new BasicScheme());
+ final AuthExchange proxyAuthExchange = new AuthExchange();
+ proxyAuthExchange.setState(AuthExchange.State.SUCCESS);
+ proxyAuthExchange.select(new NTLMScheme());
+ context.setAuthExchange(target, targetAuthExchange);
+ context.setAuthExchange(proxy, proxyAuthExchange);
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ final ClassicHttpResponse response2 = Mockito.mock(ClassicHttpResponse.class);
+ final HttpHost otherHost = new HttpHost("otherhost", 8888);
+ final URI redirect = new URI("http://otherhost:8888/redirect");
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(chain.proceed(
+ HttpRequestMatcher.matchesRequestUri(redirect),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response2);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.when(redirectStrategy.getLocationURI(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(redirect);
+ Mockito.when(httpRoutePlanner.determineRoute(
+ Mockito.eq(target),
+ Mockito.<HttpClientContext>any())).thenReturn(new HttpRoute(target));
+ Mockito.when(httpRoutePlanner.determineRoute(
+ Mockito.eq(otherHost),
+ Mockito.<HttpClientContext>any())).thenReturn(new HttpRoute(otherHost));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ redirectExec.execute(request, scope, chain);
+
+ final AuthExchange authExchange1 = context.getAuthExchange(target);
+ Assert.assertNotNull(authExchange1);
+ Assert.assertEquals(AuthExchange.State.UNCHALLENGED, authExchange1.getState());
+ Assert.assertEquals(null, authExchange1.getAuthScheme());
+ final AuthExchange authExchange2 = context.getAuthExchange(proxy);
+ Assert.assertNotNull(authExchange2);
+ Assert.assertEquals(AuthExchange.State.UNCHALLENGED, authExchange2.getState());
+ Assert.assertEquals(null, authExchange2.getAuthScheme());
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testRedirectRuntimeException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.doThrow(new RuntimeException("Oppsie")).when(redirectStrategy.getLocationURI(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any()));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ redirectExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(response1).close();
+ throw ex;
+ }
+ }
+
+ @Test(expected = ProtocolException.class)
+ public void testRedirectProtocolException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response1 = Mockito.mock(ClassicHttpResponse.class);
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ final HttpEntity entity1 = EntityBuilder.create()
+ .setStream(instream1)
+ .build();
+ Mockito.when(response1.getEntity()).thenReturn(entity1);
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response1);
+ Mockito.when(redirectStrategy.isRedirected(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.doThrow(new ProtocolException("Oppsie")).when(redirectStrategy).getLocationURI(
+ Mockito.same(request),
+ Mockito.same(response1),
+ Mockito.<HttpClientContext>any());
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ redirectExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(instream1).close();
+ Mockito.verify(response1).close();
+ throw ex;
+ }
+ }
+
+ private static class HttpRequestMatcher implements ArgumentMatcher<ClassicHttpRequest> {
+
+ private final URI requestUri;
+
+ HttpRequestMatcher(final URI requestUri) {
+ super();
+ this.requestUri = requestUri;
+ }
+
+ @Override
+ public boolean matches(final ClassicHttpRequest argument) {
+ try {
+ return requestUri.equals(argument.getUri());
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ static ClassicHttpRequest matchesRequestUri(final URI requestUri) {
+ return ArgumentMatchers.argThat(new HttpRequestMatcher(requestUri));
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestResponseEntityWrapper.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestResponseEntityWrapper.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestResponseEntityWrapper.java
new file mode 100644
index 0000000..46250cf
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestResponseEntityWrapper.java
@@ -0,0 +1,142 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketException;
+
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+@SuppressWarnings("boxing") // test code
+public class TestResponseEntityWrapper {
+
+ private InputStream instream;
+ private HttpEntity entity;
+ private ExecRuntime execRuntime;
+ private ResponseEntityProxy wrapper;
+
+ @Before
+ public void setup() throws Exception {
+ instream = Mockito.mock(InputStream.class);
+ entity = Mockito.mock(HttpEntity.class);
+ Mockito.when(entity.getContent()).thenReturn(instream);
+ execRuntime = Mockito.mock(ExecRuntime.class);
+ wrapper = new ResponseEntityProxy(entity, execRuntime);
+ }
+
+ @Test
+ public void testReusableEntityStreamClosed() throws Exception {
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ EntityUtils.consume(wrapper);
+
+ Mockito.verify(instream, Mockito.times(1)).close();
+ Mockito.verify(execRuntime).releaseConnection();
+ }
+
+ @Test
+ public void testReusableEntityStreamClosedIOError() throws Exception {
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ Mockito.doThrow(new IOException()).when(instream).close();
+ try {
+ EntityUtils.consume(wrapper);
+ Assert.fail("IOException expected");
+ } catch (final IOException ex) {
+ }
+ Mockito.verify(execRuntime, Mockito.atLeast(1)).discardConnection();
+ }
+
+ @Test
+ public void testEntityStreamClosedIOErrorAlreadyReleased() throws Exception {
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionAcquired()).thenReturn(false);
+ Mockito.doThrow(new SocketException()).when(instream).close();
+ EntityUtils.consume(wrapper);
+ Mockito.verify(execRuntime).discardConnection();
+ }
+
+ @Test
+ public void testReusableEntityWriteTo() throws Exception {
+ final OutputStream outstream = Mockito.mock(OutputStream.class);
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ wrapper.writeTo(outstream);
+ Mockito.verify(execRuntime).releaseConnection();
+ }
+
+ @Test
+ public void testReusableEntityWriteToIOError() throws Exception {
+ final OutputStream outstream = Mockito.mock(OutputStream.class);
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ Mockito.doThrow(new IOException()).when(entity).writeTo(outstream);
+ try {
+ wrapper.writeTo(outstream);
+ Assert.fail("IOException expected");
+ } catch (final IOException ex) {
+ }
+ Mockito.verify(execRuntime, Mockito.never()).releaseConnection();
+ Mockito.verify(execRuntime, Mockito.atLeast(1)).discardConnection();
+ }
+
+ @Test
+ public void testReusableEntityEndOfStream() throws Exception {
+ Mockito.when(instream.read()).thenReturn(-1);
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ final InputStream content = wrapper.getContent();
+ Assert.assertEquals(-1, content.read());
+ Mockito.verify(instream).close();
+ Mockito.verify(execRuntime).releaseConnection();
+ }
+
+ @Test
+ public void testReusableEntityEndOfStreamIOError() throws Exception {
+ Mockito.when(instream.read()).thenReturn(-1);
+ Mockito.when(entity.isStreaming()).thenReturn(true);
+ Mockito.when(execRuntime.isConnectionReusable()).thenReturn(true);
+ Mockito.doThrow(new IOException()).when(instream).close();
+ final InputStream content = wrapper.getContent();
+ try {
+ content.read();
+ Assert.fail("IOException expected");
+ } catch (final IOException ex) {
+ }
+ Mockito.verify(execRuntime, Mockito.atLeast(1)).discardConnection();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRetryExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRetryExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRetryExec.java
new file mode 100644
index 0000000..d21a022
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestRetryExec.java
@@ -0,0 +1,188 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.hc.client5.http.HttpRequestRetryHandler;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.NonRepeatableRequestException;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.impl.ExecSupport;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestRetryExec {
+
+ @Mock
+ private HttpRequestRetryHandler retryHandler;
+ @Mock
+ private ExecRuntime endpoint;
+ @Mock
+ private ExecChain chain;
+
+ private RetryExec retryExec;
+ private HttpHost target;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ retryExec = new RetryExec(retryHandler);
+ target = new HttpHost("localhost", 80);
+ }
+
+ @Test(expected = IOException.class)
+ public void testFundamentals() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet originalRequest = new HttpGet("/test");
+ originalRequest.addHeader("header", "this");
+ originalRequest.addHeader("header", "that");
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
+
+ @Override
+ public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ final Object[] args = invocationOnMock.getArguments();
+ final ClassicHttpRequest wrapper = (ClassicHttpRequest) args[0];
+ final Header[] headers = wrapper.getAllHeaders();
+ Assert.assertEquals(2, headers.length);
+ Assert.assertEquals("this", headers[0].getValue());
+ Assert.assertEquals("that", headers[1].getValue());
+ wrapper.addHeader("Cookie", "monster");
+ throw new IOException("Ka-boom");
+ }
+
+ });
+ Mockito.when(retryHandler.retryRequest(
+ Mockito.<HttpRequest>any(),
+ Mockito.<IOException>any(),
+ Mockito.eq(1),
+ Mockito.<HttpContext>any())).thenReturn(Boolean.TRUE);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, originalRequest, endpoint, context);
+ final ClassicHttpRequest request = ExecSupport.copy(originalRequest);
+ try {
+ retryExec.execute(request, scope, chain);
+ } catch (final IOException ex) {
+ Mockito.verify(chain, Mockito.times(2)).proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.same(scope));
+ throw ex;
+ }
+ }
+
+ @Test(expected = IOException.class)
+ public void testAbortedRequest() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet originalRequest = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenThrow(new IOException("Ka-boom"));
+ Mockito.when(endpoint.isExecutionAborted()).thenReturn(true);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, originalRequest, endpoint, context);
+ final ClassicHttpRequest request = ExecSupport.copy(originalRequest);
+ try {
+ retryExec.execute(request, scope, chain);
+ } catch (final IOException ex) {
+ Mockito.verify(chain, Mockito.times(1)).proceed(
+ Mockito.same(request),
+ Mockito.same(scope));
+ Mockito.verify(retryHandler, Mockito.never()).retryRequest(
+ Mockito.<HttpRequest>any(),
+ Mockito.<IOException>any(),
+ Mockito.anyInt(),
+ Mockito.<HttpContext>any());
+
+ throw ex;
+ }
+ }
+
+ @Test(expected = NonRepeatableRequestException.class)
+ public void testNonRepeatableRequest() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpPost originalRequest = new HttpPost("/test");
+ originalRequest.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
+
+ @Override
+ public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ final Object[] args = invocationOnMock.getArguments();
+ final ClassicHttpRequest req = (ClassicHttpRequest) args[0];
+ req.getEntity().writeTo(new ByteArrayOutputStream());
+ throw new IOException("Ka-boom");
+ }
+
+ });
+ Mockito.when(retryHandler.retryRequest(
+ Mockito.<HttpRequest>any(),
+ Mockito.<IOException>any(),
+ Mockito.eq(1),
+ Mockito.<HttpContext>any())).thenReturn(Boolean.TRUE);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, originalRequest, endpoint, context);
+ final ClassicHttpRequest request = ExecSupport.copy(originalRequest);
+ try {
+ retryExec.execute(request, scope, chain);
+ } catch (final IOException ex) {
+ Mockito.verify(chain, Mockito.times(1)).proceed(
+ Mockito.same(request),
+ Mockito.same(scope));
+
+ throw ex;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestServiceUnavailableRetryExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestServiceUnavailableRetryExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestServiceUnavailableRetryExec.java
new file mode 100644
index 0000000..f6ab7b3
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestServiceUnavailableRetryExec.java
@@ -0,0 +1,148 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.ServiceUnavailableRetryStrategy;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestServiceUnavailableRetryExec {
+
+ @Mock
+ private ServiceUnavailableRetryStrategy retryStrategy;
+ @Mock
+ private ExecChain chain;
+ @Mock
+ private ExecRuntime endpoint;
+
+ private ServiceUnavailableRetryExec retryExec;
+ private HttpHost target;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ retryExec = new ServiceUnavailableRetryExec(retryStrategy);
+ target = new HttpHost("localhost", 80);
+ }
+
+ @Test
+ public void testFundamentals() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpGet request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+
+ Mockito.when(chain.proceed(
+ Mockito.same(request),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.when(retryStrategy.retryRequest(
+ Mockito.<HttpResponse>any(),
+ Mockito.anyInt(),
+ Mockito.<HttpContext>any())).thenReturn(Boolean.TRUE, Boolean.FALSE);
+ Mockito.when(retryStrategy.getRetryInterval(
+ Mockito.<HttpResponse>any(),
+ Mockito.<HttpContext>any())).thenReturn(0L);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ retryExec.execute(request, scope, chain);
+
+ Mockito.verify(chain, Mockito.times(2)).proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.same(scope));
+ Mockito.verify(response, Mockito.times(1)).close();
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testStrategyRuntimeException() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final ClassicHttpRequest request = new HttpGet("/test");
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.doThrow(new RuntimeException("Ooopsie")).when(retryStrategy).retryRequest(
+ Mockito.<HttpResponse>any(),
+ Mockito.anyInt(),
+ Mockito.<HttpContext>any());
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ try {
+ retryExec.execute(request, scope, chain);
+ } catch (final Exception ex) {
+ Mockito.verify(response).close();
+ throw ex;
+ }
+ }
+
+ @Test
+ public void testNonRepeatableEntityResponseReturnedImmediately() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+
+ final HttpPost request = new HttpPost("/test");
+ request.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+ final HttpClientContext context = HttpClientContext.create();
+
+ final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+ Mockito.when(chain.proceed(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any())).thenReturn(response);
+ Mockito.when(retryStrategy.retryRequest(
+ Mockito.<HttpResponse>any(),
+ Mockito.anyInt(),
+ Mockito.<HttpContext>any())).thenReturn(Boolean.TRUE, Boolean.FALSE);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ClassicHttpResponse finalResponse = retryExec.execute(request, scope, chain);
+
+ Assert.assertSame(response, finalResponse);
+ Mockito.verify(response, Mockito.times(0)).close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/protocol/TestAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/protocol/TestAuthenticationStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/protocol/TestAuthenticationStrategy.java
deleted file mode 100644
index 35de833..0000000
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/protocol/TestAuthenticationStrategy.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.protocol;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.hc.client5.http.auth.AuthChallenge;
-import org.apache.hc.client5.http.auth.AuthScheme;
-import org.apache.hc.client5.http.auth.AuthSchemeProvider;
-import org.apache.hc.client5.http.auth.AuthScope;
-import org.apache.hc.client5.http.auth.ChallengeType;
-import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.config.AuthSchemes;
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.impl.auth.BasicScheme;
-import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
-import org.apache.hc.client5.http.impl.auth.DigestScheme;
-import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
-import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.core5.http.config.Registry;
-import org.apache.hc.core5.http.config.RegistryBuilder;
-import org.apache.hc.core5.http.message.BasicNameValuePair;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Simple tests for {@link DefaultAuthenticationStrategy}.
- */
-@SuppressWarnings("boxing") // test code
-public class TestAuthenticationStrategy {
-
- @Test
- public void testSelectInvalidInput() throws Exception {
- final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
- final HttpClientContext context = HttpClientContext.create();
- try {
- authStrategy.select(null, Collections.<String, AuthChallenge>emptyMap(), context);
- Assert.fail("IllegalArgumentException expected");
- } catch (final IllegalArgumentException ex) {
- }
- try {
- authStrategy.select(ChallengeType.TARGET, null, context);
- Assert.fail("IllegalArgumentException expected");
- } catch (final IllegalArgumentException ex) {
- }
- try {
- authStrategy.select(ChallengeType.TARGET, Collections.<String, AuthChallenge>emptyMap(), null);
- Assert.fail("IllegalArgumentException expected");
- } catch (final IllegalArgumentException ex) {
- }
- }
-
- @Test
- public void testSelectNoSchemeRegistry() throws Exception {
- final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
- final HttpClientContext context = HttpClientContext.create();
-
- final Map<String, AuthChallenge> challenges = new HashMap<>();
- challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
- new BasicNameValuePair("realm", "test")));
- challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
- new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234")));
-
- final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
- Assert.assertNotNull(authSchemes);
- Assert.assertEquals(0, authSchemes.size());
- }
-
- @Test
- public void testUnsupportedScheme() throws Exception {
- final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
- final HttpClientContext context = HttpClientContext.create();
-
- final Map<String, AuthChallenge> challenges = new HashMap<>();
- challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
- new BasicNameValuePair("realm", "realm1")));
- challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
- new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
- challenges.put("whatever", new AuthChallenge(ChallengeType.TARGET, "Whatever",
- new BasicNameValuePair("realm", "realm3")));
-
- final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
- .register("basic", new BasicSchemeFactory())
- .register("digest", new DigestSchemeFactory()).build();
- context.setAuthSchemeRegistry(authSchemeRegistry);
-
- final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(new AuthScope("somehost", 80),
- new UsernamePasswordCredentials("user", "pwd".toCharArray()));
- context.setCredentialsProvider(credentialsProvider);
-
- final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
- Assert.assertNotNull(authSchemes);
- Assert.assertEquals(2, authSchemes.size());
- final AuthScheme authScheme1 = authSchemes.get(0);
- Assert.assertTrue(authScheme1 instanceof DigestScheme);
- final AuthScheme authScheme2 = authSchemes.get(1);
- Assert.assertTrue(authScheme2 instanceof BasicScheme);
- }
-
- @Test
- public void testCustomAuthPreference() throws Exception {
- final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
- final RequestConfig config = RequestConfig.custom()
- .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
- .build();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final Map<String, AuthChallenge> challenges = new HashMap<>();
- challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
- new BasicNameValuePair("realm", "realm1")));
- challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
- new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
-
- final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
- .register("basic", new BasicSchemeFactory())
- .register("digest", new DigestSchemeFactory()).build();
- context.setAuthSchemeRegistry(authSchemeRegistry);
- context.setRequestConfig(config);
-
- final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(new AuthScope("somehost", 80),
- new UsernamePasswordCredentials("user", "pwd".toCharArray()));
- context.setCredentialsProvider(credentialsProvider);
-
- final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
- Assert.assertNotNull(authSchemes);
- Assert.assertEquals(1, authSchemes.size());
- final AuthScheme authScheme1 = authSchemes.get(0);
- Assert.assertTrue(authScheme1 instanceof BasicScheme);
- }
-
-}