HTTPCLIENT-1359: repeated requests using the same context fail if they redirect
Contributed by James Leigh <james at 3roundstones.com> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1487463 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2bd70ff44c
commit
b8c0487c91
|
@ -1,6 +1,9 @@
|
||||||
Changes since release 4.3 BETA1
|
Changes since release 4.3 BETA1
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* [HTTPCLIENT-1359] repeated requests using the same context fail if they redirect.
|
||||||
|
Contributed by James Leigh <james at 3roundstones.com>
|
||||||
|
|
||||||
* [HTTPCLIENT-1354] do not quote algorithm parameter in DIGEST auth response.
|
* [HTTPCLIENT-1354] do not quote algorithm parameter in DIGEST auth response.
|
||||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.apache.http.auth.AuthScheme;
|
||||||
import org.apache.http.auth.AuthState;
|
import org.apache.http.auth.AuthState;
|
||||||
import org.apache.http.client.RedirectException;
|
import org.apache.http.client.RedirectException;
|
||||||
import org.apache.http.client.RedirectStrategy;
|
import org.apache.http.client.RedirectStrategy;
|
||||||
|
import org.apache.http.client.URICollection;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpExecutionAware;
|
import org.apache.http.client.methods.HttpExecutionAware;
|
||||||
|
@ -87,6 +88,11 @@ public class RedirectExec implements ClientExecChain {
|
||||||
Args.notNull(request, "HTTP request");
|
Args.notNull(request, "HTTP request");
|
||||||
Args.notNull(context, "HTTP context");
|
Args.notNull(context, "HTTP context");
|
||||||
|
|
||||||
|
final URICollection redirectLocations = context.getRedirectLocations();
|
||||||
|
if (redirectLocations != null) {
|
||||||
|
redirectLocations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
final RequestConfig config = context.getRequestConfig();
|
final RequestConfig config = context.getRequestConfig();
|
||||||
final int maxRedirects = config.getMaxRedirects() > 0 ? config.getMaxRedirects() : 50;
|
final int maxRedirects = config.getMaxRedirects() > 0 ? config.getMaxRedirects() : 50;
|
||||||
HttpRoute currentRoute = route;
|
HttpRoute currentRoute = route;
|
||||||
|
|
|
@ -272,26 +272,38 @@ public class TestDefaultRedirectStrategy {
|
||||||
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
|
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
|
||||||
final HttpGet httpget = new HttpGet("http://localhost/");
|
|
||||||
final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(true).build();
|
final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(true).build();
|
||||||
context.setRequestConfig(config);
|
context.setRequestConfig(config);
|
||||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
final URI uri1 = URI.create("http://localhost/stuff1");
|
||||||
|
final URI uri2 = URI.create("http://localhost/stuff2");
|
||||||
|
final URI uri3 = URI.create("http://localhost/stuff3");
|
||||||
|
final HttpGet httpget1 = new HttpGet("http://localhost/");
|
||||||
|
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
|
HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
|
||||||
response.addHeader("Location", "http://localhost/stuff");
|
response1.addHeader("Location", uri1.toASCIIString());
|
||||||
final URI uri = URI.create("http://localhost/stuff");
|
final HttpGet httpget2 = new HttpGet(uri1.toASCIIString());
|
||||||
Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context));
|
final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
||||||
Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context));
|
HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
|
||||||
Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context));
|
response2.addHeader("Location", uri2.toASCIIString());
|
||||||
|
final HttpGet httpget3 = new HttpGet(uri2.toASCIIString());
|
||||||
|
final HttpResponse response3 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
||||||
|
HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
|
||||||
|
response3.addHeader("Location", uri3.toASCIIString());
|
||||||
|
Assert.assertEquals(uri1, redirectStrategy.getLocationURI(httpget1, response1, context));
|
||||||
|
Assert.assertEquals(uri2, redirectStrategy.getLocationURI(httpget2, response2, context));
|
||||||
|
Assert.assertEquals(uri3, redirectStrategy.getLocationURI(httpget3, response3, context));
|
||||||
|
|
||||||
final URICollection redirectLocations = context.getRedirectLocations();
|
final URICollection redirectLocations = context.getRedirectLocations();
|
||||||
Assert.assertNotNull(redirectLocations);
|
Assert.assertNotNull(redirectLocations);
|
||||||
Assert.assertTrue(redirectLocations.contains(uri));
|
Assert.assertTrue(redirectLocations.contains(uri1));
|
||||||
|
Assert.assertTrue(redirectLocations.contains(uri2));
|
||||||
|
Assert.assertTrue(redirectLocations.contains(uri3));
|
||||||
final List<URI> uris = redirectLocations.getAll();
|
final List<URI> uris = redirectLocations.getAll();
|
||||||
Assert.assertNotNull(uris);
|
Assert.assertNotNull(uris);
|
||||||
Assert.assertEquals(3, uris.size());
|
Assert.assertEquals(3, uris.size());
|
||||||
Assert.assertEquals(uri, uris.get(0));
|
Assert.assertEquals(uri1, uris.get(0));
|
||||||
Assert.assertEquals(uri, uris.get(1));
|
Assert.assertEquals(uri2, uris.get(1));
|
||||||
Assert.assertEquals(uri, uris.get(2));
|
Assert.assertEquals(uri3, uris.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ProtocolException.class)
|
@Test(expected=ProtocolException.class)
|
||||||
|
@ -299,7 +311,7 @@ public class TestDefaultRedirectStrategy {
|
||||||
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
|
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
|
||||||
final HttpGet httpget = new HttpGet("http://localhost/");
|
final HttpGet httpget = new HttpGet("http://localhost/stuff");
|
||||||
final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(false).build();
|
final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(false).build();
|
||||||
context.setRequestConfig(config);
|
context.setRequestConfig(config);
|
||||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
|
||||||
|
|
|
@ -182,6 +182,28 @@ public class TestRedirects extends IntegrationTestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class RomeRedirectService implements HttpRequestHandler {
|
||||||
|
|
||||||
|
public RomeRedirectService() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(
|
||||||
|
final HttpRequest request,
|
||||||
|
final HttpResponse response,
|
||||||
|
final HttpContext context) throws HttpException, IOException {
|
||||||
|
final String uri = request.getRequestLine().getUri();
|
||||||
|
if (uri.equals("/rome")) {
|
||||||
|
response.setStatusCode(HttpStatus.SC_OK);
|
||||||
|
final StringEntity entity = new StringEntity("Successful redirect");
|
||||||
|
response.setEntity(entity);
|
||||||
|
} else {
|
||||||
|
response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||||
|
response.addHeader(new BasicHeader("Location", "/rome"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class BogusRedirectService implements HttpRequestHandler {
|
private static class BogusRedirectService implements HttpRequestHandler {
|
||||||
private final String url;
|
private final String url;
|
||||||
|
|
||||||
|
@ -426,6 +448,89 @@ public class TestRedirects extends IntegrationTestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepeatRequest() throws Exception {
|
||||||
|
final HttpHost target = getServerHttp();
|
||||||
|
this.localServer.register("*", new RomeRedirectService());
|
||||||
|
|
||||||
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
|
||||||
|
final HttpGet first = new HttpGet("/rome");
|
||||||
|
first.setConfig(config);
|
||||||
|
|
||||||
|
EntityUtils.consume(this.httpclient.execute(target, first, context).getEntity());
|
||||||
|
|
||||||
|
final HttpGet second = new HttpGet("/rome");
|
||||||
|
second.setConfig(config);
|
||||||
|
|
||||||
|
final HttpResponse response = this.httpclient.execute(target, second, context);
|
||||||
|
EntityUtils.consume(response.getEntity());
|
||||||
|
|
||||||
|
final HttpRequest reqWrapper = context.getRequest();
|
||||||
|
final HttpHost host = context.getTargetHost();
|
||||||
|
|
||||||
|
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||||
|
Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
|
||||||
|
Assert.assertEquals(host, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepeatRequestRedirect() throws Exception {
|
||||||
|
final HttpHost target = getServerHttp();
|
||||||
|
this.localServer.register("*", new RomeRedirectService());
|
||||||
|
|
||||||
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
|
||||||
|
final HttpGet first = new HttpGet("/lille");
|
||||||
|
first.setConfig(config);
|
||||||
|
|
||||||
|
final HttpResponse response1 = this.httpclient.execute(target, first, context);
|
||||||
|
EntityUtils.consume(response1.getEntity());
|
||||||
|
|
||||||
|
final HttpGet second = new HttpGet("/lille");
|
||||||
|
second.setConfig(config);
|
||||||
|
|
||||||
|
final HttpResponse response2 = this.httpclient.execute(target, second, context);
|
||||||
|
EntityUtils.consume(response2.getEntity());
|
||||||
|
|
||||||
|
final HttpRequest reqWrapper = context.getRequest();
|
||||||
|
final HttpHost host = context.getTargetHost();
|
||||||
|
|
||||||
|
Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
|
||||||
|
Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
|
||||||
|
Assert.assertEquals(host, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentRequestSameRedirect() throws Exception {
|
||||||
|
final HttpHost target = getServerHttp();
|
||||||
|
this.localServer.register("*", new RomeRedirectService());
|
||||||
|
|
||||||
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
|
||||||
|
final HttpGet first = new HttpGet("/alian");
|
||||||
|
first.setConfig(config);
|
||||||
|
|
||||||
|
final HttpResponse response1 = this.httpclient.execute(target, first, context);
|
||||||
|
EntityUtils.consume(response1.getEntity());
|
||||||
|
|
||||||
|
final HttpGet second = new HttpGet("/lille");
|
||||||
|
second.setConfig(config);
|
||||||
|
|
||||||
|
final HttpResponse response2 = this.httpclient.execute(target, second, context);
|
||||||
|
EntityUtils.consume(response2.getEntity());
|
||||||
|
|
||||||
|
final HttpRequest reqWrapper = context.getRequest();
|
||||||
|
final HttpHost host = context.getTargetHost();
|
||||||
|
|
||||||
|
Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
|
||||||
|
Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
|
||||||
|
Assert.assertEquals(host, target);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostNoRedirect() throws Exception {
|
public void testPostNoRedirect() throws Exception {
|
||||||
final HttpHost target = getServerHttp();
|
final HttpHost target = getServerHttp();
|
||||||
|
|
Loading…
Reference in New Issue