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/05/01 13:06:48 UTC
svn commit: r1793325 [2/2] - in
/httpcomponents/httpclient/trunk/httpclient5/src:
main/java/org/apache/hc/client5/http/impl/sync/
test/java/org/apache/hc/client5/http/impl/sync/
Modified: httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestMainClientExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestMainClientExec.java?rev=1793325&r1=1793324&r2=1793325&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestMainClientExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestMainClientExec.java Mon May 1 13:06:48 2017
@@ -27,52 +27,28 @@
package org.apache.hc.client5.http.impl.sync;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InterruptedIOException;
-import java.util.Collections;
-import java.util.Map;
import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
import org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.RouteInfo;
-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.UsernamePasswordCredentials;
import org.apache.hc.client5.http.entity.EntityBuilder;
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
-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.AuthenticationStrategy;
import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.protocol.NonRepeatableRequestException;
import org.apache.hc.client5.http.protocol.UserTokenHandler;
import org.apache.hc.client5.http.sync.ExecChain;
import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.client5.http.sync.methods.HttpPost;
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.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.util.TimeValue;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -87,27 +63,18 @@ public class TestMainClientExec {
@Mock
private ConnectionKeepAliveStrategy keepAliveStrategy;
@Mock
- private HttpProcessor proxyHttpProcessor;
- @Mock
- private AuthenticationStrategy targetAuthStrategy;
- @Mock
- private AuthenticationStrategy proxyAuthStrategy;
- @Mock
private UserTokenHandler userTokenHandler;
@Mock
private ExecRuntime endpoint;
private MainClientExec mainClientExec;
private HttpHost target;
- private HttpHost proxy;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
- mainClientExec = new MainClientExec(reuseStrategy, keepAliveStrategy, proxyHttpProcessor, targetAuthStrategy,
- proxyAuthStrategy, userTokenHandler);
+ mainClientExec = new MainClientExec(reuseStrategy, keepAliveStrategy, userTokenHandler);
target = new HttpHost("foo", 80);
- proxy = new HttpHost("bar", 8888);
}
@Test
@@ -131,8 +98,6 @@ public class TestMainClientExec {
final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint).acquireConnection(route, null, context);
- Mockito.verify(endpoint).connect(context);
Mockito.verify(endpoint).execute(request, context);
Mockito.verify(endpoint, Mockito.times(1)).markConnectionNonReusable();
Mockito.verify(endpoint, Mockito.never()).releaseConnection();
@@ -162,8 +127,6 @@ public class TestMainClientExec {
final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint).acquireConnection(route, null, context);
- Mockito.verify(endpoint).connect(context);
Mockito.verify(endpoint).execute(request, context);
Mockito.verify(endpoint).markConnectionNonReusable();
Mockito.verify(endpoint).releaseConnection();
@@ -200,8 +163,6 @@ public class TestMainClientExec {
final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint).acquireConnection(route, null, context);
- Mockito.verify(endpoint).connect(context);
Mockito.verify(endpoint).execute(request, context);
Mockito.verify(endpoint).markConnectionReusable();
Mockito.verify(endpoint, Mockito.never()).releaseConnection();
@@ -234,8 +195,6 @@ public class TestMainClientExec {
final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint).acquireConnection(route, null, context);
- Mockito.verify(endpoint).connect(context);
Mockito.verify(endpoint).execute(request, context);
Mockito.verify(endpoint).releaseConnection();
@@ -355,355 +314,6 @@ public class TestMainClientExec {
}
}
- @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);
-
- 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(response1, response2);
- Mockito.when(reuseStrategy.keepAlive(
- Mockito.same(request),
- Mockito.<HttpResponse>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
- Mockito.when(targetAuthStrategy.select(
- Mockito.eq(ChallengeType.TARGET),
- Mockito.<Map<String, AuthChallenge>>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
- Mockito.when(endpoint.isConnectionReusable()).thenReturn(true);
-
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
- final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint, Mockito.times(2)).execute(request, context);
- 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);
-
- 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(response1, response2);
- Mockito.when(reuseStrategy.keepAlive(
- Mockito.same(request),
- Mockito.<HttpResponse>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
-
- 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, endpoint, context);
- final ClassicHttpResponse finalResponse = mainClientExec.execute(request, scope, null);
- Mockito.verify(endpoint, Mockito.times(2)).execute(request, context);
- Mockito.verify(endpoint).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);
-
- 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())).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(reuseStrategy.keepAlive(
- Mockito.same(request),
- Mockito.<HttpResponse>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
-
- 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, endpoint, context);
- mainClientExec.execute(request, scope, null);
- }
-
- @Test
- public void testEstablishDirectRoute() throws Exception {
- final HttpRoute route = new HttpRoute(target);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
-
- final ConnectionState connectionState = new ConnectionState();
- Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
- Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
-
- mainClientExec.establishRoute(route, request, endpoint, context);
-
- Mockito.verify(endpoint).connect(context);
- Mockito.verify(endpoint, Mockito.never()).execute(Mockito.<ClassicHttpRequest>any(), Mockito.<HttpClientContext>any());
- }
-
- @Test
- public void testEstablishRouteDirectProxy() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, false);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
-
- final ConnectionState connectionState = new ConnectionState();
- Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
- Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
-
- mainClientExec.establishRoute(route, request, endpoint, context);
-
- Mockito.verify(endpoint).connect(context);
- Mockito.verify(endpoint, Mockito.never()).execute(Mockito.<ClassicHttpRequest>any(), Mockito.<HttpClientContext>any());
- }
-
- @Test
- public void testEstablishRouteViaProxyTunnel() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, true);
- 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.<ClassicHttpRequest>any(),
- Mockito.<HttpClientContext>any())).thenReturn(response);
-
- mainClientExec.establishRoute(route, request, endpoint, context);
-
- Mockito.verify(endpoint).connect(context);
- final ArgumentCaptor<ClassicHttpRequest> reqCaptor = ArgumentCaptor.forClass(ClassicHttpRequest.class);
- Mockito.verify(endpoint).execute(
- reqCaptor.capture(),
- Mockito.same(context));
- final HttpRequest connect = reqCaptor.getValue();
- Assert.assertNotNull(connect);
- Assert.assertEquals("CONNECT", connect.getMethod());
- Assert.assertEquals(HttpVersion.HTTP_1_1, connect.getVersion());
- Assert.assertEquals("foo:80", connect.getRequestUri());
- }
-
- @Test(expected = HttpException.class)
- public void testEstablishRouteViaProxyTunnelUnexpectedResponse() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, true);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
- final ClassicHttpResponse response = new BasicClassicHttpResponse(101, "Lost");
-
- 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.<ClassicHttpRequest>any(),
- Mockito.<HttpClientContext>any())).thenReturn(response);
-
- mainClientExec.establishRoute(route, request, endpoint, context);
- }
-
- @Test(expected = HttpException.class)
- public void testEstablishRouteViaProxyTunnelFailure() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, true);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
- final ClassicHttpResponse response = new BasicClassicHttpResponse(500, "Boom");
- response.setEntity(new StringEntity("Ka-boom"));
-
- 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.<ClassicHttpRequest>any(),
- Mockito.<HttpClientContext>any())).thenReturn(response);
-
- try {
- mainClientExec.establishRoute(route, request, endpoint, context);
- } catch (final TunnelRefusedException ex) {
- final ClassicHttpResponse r = ex.getResponse();
- Assert.assertEquals("Ka-boom", EntityUtils.toString(r.getEntity()));
- Mockito.verify(endpoint).disconnect();
- Mockito.verify(endpoint).discardConnection();
- throw ex;
- }
- }
-
- @Test
- public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengePersistentConnection() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, true);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
- final ClassicHttpResponse response1 = new BasicClassicHttpResponse(407, "Huh?");
- response1.setHeader(HttpHeaders.PROXY_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 BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user", "pass".toCharArray()));
- context.setCredentialsProvider(credentialsProvider);
-
- final ConnectionState connectionState = new ConnectionState();
- Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
- Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
- Mockito.when(reuseStrategy.keepAlive(
- Mockito.same(request),
- Mockito.<HttpResponse>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
- Mockito.when(endpoint.execute(
- Mockito.<ClassicHttpRequest>any(),
- Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
-
- Mockito.when(proxyAuthStrategy.select(
- Mockito.eq(ChallengeType.PROXY),
- Mockito.<Map<String, AuthChallenge>>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
-
- mainClientExec.establishRoute(route, request, endpoint, context);
-
- Mockito.verify(endpoint).connect(context);
- Mockito.verify(instream1).close();
- }
-
- @Test
- public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengeNonPersistentConnection() throws Exception {
- final HttpRoute route = new HttpRoute(target, null, proxy, true);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
- final ClassicHttpResponse response1 = new BasicClassicHttpResponse(407, "Huh?");
- response1.setHeader(HttpHeaders.PROXY_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 BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user", "pass".toCharArray()));
- context.setCredentialsProvider(credentialsProvider);
-
- final ConnectionState connectionState = new ConnectionState();
- Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
- Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
- Mockito.when(reuseStrategy.keepAlive(
- Mockito.same(request),
- Mockito.<HttpResponse>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
- Mockito.when(endpoint.execute(
- Mockito.<ClassicHttpRequest>any(),
- Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
-
- Mockito.when(proxyAuthStrategy.select(
- Mockito.eq(ChallengeType.PROXY),
- Mockito.<Map<String, AuthChallenge>>any(),
- Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
-
- mainClientExec.establishRoute(route, request, endpoint, context);
-
- Mockito.verify(endpoint).connect(context);
- Mockito.verify(instream1, Mockito.never()).close();
- Mockito.verify(endpoint).disconnect();
- }
-
- @Test(expected = HttpException.class)
- public void testEstablishRouteViaProxyTunnelMultipleHops() throws Exception {
- final HttpHost proxy1 = new HttpHost("this", 8888);
- final HttpHost proxy2 = new HttpHost("that", 8888);
- final HttpRoute route = new HttpRoute(target, null, new HttpHost[] {proxy1, proxy2},
- true, RouteInfo.TunnelType.TUNNELLED, RouteInfo.LayerType.LAYERED);
- final HttpClientContext context = new HttpClientContext();
- final ClassicHttpRequest request = new HttpGet("http://bar/test");
-
- final ConnectionState connectionState = new ConnectionState();
- Mockito.doAnswer(connectionState.connectAnswer()).when(endpoint).connect(Mockito.<HttpClientContext>any());
- Mockito.when(endpoint.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
-
- mainClientExec.establishRoute(route, request, endpoint, context);
- }
-
static class ConnectionState {
private boolean connected;
Modified: httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestProtocolExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestProtocolExec.java?rev=1793325&r1=1793324&r2=1793325&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestProtocolExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestProtocolExec.java Mon May 1 13:06:48 2017
@@ -26,22 +26,41 @@
*/
package org.apache.hc.client5.http.impl.sync;
+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.HttpRoute;
+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.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.AuthenticationStrategy;
import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.protocol.NonRepeatableRequestException;
import org.apache.hc.client5.http.sync.ExecChain;
import org.apache.hc.client5.http.sync.ExecRuntime;
import org.apache.hc.client5.http.sync.methods.HttpGet;
+import org.apache.hc.client5.http.sync.methods.HttpPost;
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;
@@ -50,6 +69,8 @@ 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 {
@@ -57,18 +78,24 @@ public class TestProtocolExec {
@Mock
private HttpProcessor httpProcessor;
@Mock
+ private AuthenticationStrategy targetAuthStrategy;
+ @Mock
+ private AuthenticationStrategy proxyAuthStrategy;
+ @Mock
private ExecChain chain;
@Mock
- private ExecRuntime endpoint;
+ 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);
+ protocolExec = new ProtocolExec(httpProcessor, targetAuthStrategy, proxyAuthStrategy);
target = new HttpHost("foo", 80);
+ proxy = new HttpHost("bar", 8888);
}
@Test
@@ -83,7 +110,7 @@ public class TestProtocolExec {
Mockito.<ClassicHttpRequest>any(),
Mockito.<ExecChain.Scope>any())).thenReturn(response);
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
protocolExec.execute(request, scope, chain);
Mockito.verify(httpProcessor).process(request, null, context);
@@ -107,7 +134,7 @@ public class TestProtocolExec {
Mockito.<ClassicHttpRequest>any(),
Mockito.<ExecChain.Scope>any())).thenReturn(response);
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ 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();
@@ -129,11 +156,11 @@ public class TestProtocolExec {
Mockito.<ExecChain.Scope>any())).thenReturn(response);
Mockito.doThrow(new HttpException("Ooopsie")).when(httpProcessor).process(
Mockito.same(response), Mockito.isNull(EntityDetails.class), Mockito.<HttpContext>any());
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
try {
protocolExec.execute(request, scope, chain);
} catch (final Exception ex) {
- Mockito.verify(response).close();
+ Mockito.verify(execRuntime).discardConnection();
throw ex;
}
}
@@ -150,11 +177,11 @@ public class TestProtocolExec {
Mockito.<ExecChain.Scope>any())).thenReturn(response);
Mockito.doThrow(new IOException("Ooopsie")).when(httpProcessor).process(
Mockito.same(response), Mockito.isNull(EntityDetails.class), Mockito.<HttpContext>any());
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
try {
protocolExec.execute(request, scope, chain);
} catch (final Exception ex) {
- Mockito.verify(response).close();
+ Mockito.verify(execRuntime).discardConnection();
throw ex;
}
}
@@ -171,13 +198,143 @@ public class TestProtocolExec {
Mockito.<ExecChain.Scope>any())).thenReturn(response);
Mockito.doThrow(new RuntimeException("Ooopsie")).when(httpProcessor).process(
Mockito.same(response), Mockito.isNull(EntityDetails.class), Mockito.<HttpContext>any());
- final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
try {
protocolExec.execute(request, scope, chain);
} catch (final Exception ex) {
- Mockito.verify(response).close();
+ 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);
+ }
+
}