HTTPCLIENT-698: Resolve non-absolute redirect URIs relative to the request URI
Contributed by Johannes Koch <johannes.koch at fit.fraunhofer.de> Reviewed by Oleg Kalnichevski git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@589630 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e445d72146
commit
243769a600
|
@ -1,5 +1,9 @@
|
||||||
Changes since release 4.0 Alpha 1
|
Changes since release 4.0 Alpha 1
|
||||||
|
|
||||||
|
* [HTTPCLIENT-698] Resolve non-absolute redirect URIs relative to
|
||||||
|
the request URI
|
||||||
|
Contributed by Johannes Koch <johannes.koch at fit.fraunhofer.de>
|
||||||
|
|
||||||
* [HTTPCLIENT-697] Throw a more intelligible exception when connection
|
* [HTTPCLIENT-697] Throw a more intelligible exception when connection
|
||||||
to a remote host cannot be established.
|
to a remote host cannot be established.
|
||||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.ProtocolException;
|
import org.apache.http.ProtocolException;
|
||||||
|
@ -131,15 +132,21 @@ public class DefaultRedirectHandler implements RedirectHandler {
|
||||||
throw new IllegalStateException("Target host not available " +
|
throw new IllegalStateException("Target host not available " +
|
||||||
"in the HTTP context");
|
"in the HTTP context");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpRequest request = (HttpRequest) context.getAttribute(
|
||||||
|
ExecutionContext.HTTP_REQUEST);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
uri = new URI(
|
URI requestURI = new URI(request.getRequestLine().getUri());
|
||||||
|
URI absoluteRequestURI = new URI(
|
||||||
target.getSchemeName(),
|
target.getSchemeName(),
|
||||||
null,
|
null,
|
||||||
target.getHostName(),
|
target.getHostName(),
|
||||||
target.getPort(),
|
target.getPort(),
|
||||||
uri.getPath(),
|
requestURI.getPath(),
|
||||||
uri.getQuery(),
|
requestURI.getQuery(),
|
||||||
uri.getFragment());
|
requestURI.getFragment());
|
||||||
|
uri = absoluteRequestURI.resolve(uri);
|
||||||
} catch (URISyntaxException ex) {
|
} catch (URISyntaxException ex) {
|
||||||
throw new ProtocolException(ex.getMessage(), ex);
|
throw new ProtocolException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,28 +158,53 @@ public class TestRedirects extends ServerTestBase {
|
||||||
|
|
||||||
private class RelativeRedirectService implements HttpRequestHandler {
|
private class RelativeRedirectService implements HttpRequestHandler {
|
||||||
|
|
||||||
public RelativeRedirectService() {
|
public RelativeRedirectService() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(
|
public void handle(
|
||||||
final HttpRequest request,
|
final HttpRequest request,
|
||||||
final HttpResponse response,
|
final HttpResponse response,
|
||||||
final HttpContext context) throws HttpException, IOException {
|
final HttpContext context) throws HttpException, IOException {
|
||||||
ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
|
ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
|
||||||
String uri = request.getRequestLine().getUri();
|
String uri = request.getRequestLine().getUri();
|
||||||
if (uri.equals("/oldlocation/")) {
|
if (uri.equals("/oldlocation/")) {
|
||||||
response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
|
response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
|
||||||
response.addHeader(new BasicHeader("Location", "/relativelocation/"));
|
response.addHeader(new BasicHeader("Location", "/relativelocation/"));
|
||||||
} else if (uri.equals("/relativelocation/")) {
|
} else if (uri.equals("/relativelocation/")) {
|
||||||
response.setStatusLine(ver, HttpStatus.SC_OK);
|
response.setStatusLine(ver, HttpStatus.SC_OK);
|
||||||
StringEntity entity = new StringEntity("Successful redirect");
|
StringEntity entity = new StringEntity("Successful redirect");
|
||||||
response.setEntity(entity);
|
response.setEntity(entity);
|
||||||
} else {
|
} else {
|
||||||
response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
|
response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RelativeRedirectService2 implements HttpRequestHandler {
|
||||||
|
|
||||||
|
public RelativeRedirectService2() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(
|
||||||
|
final HttpRequest request,
|
||||||
|
final HttpResponse response,
|
||||||
|
final HttpContext context) throws HttpException, IOException {
|
||||||
|
ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
|
||||||
|
String uri = request.getRequestLine().getUri();
|
||||||
|
if (uri.equals("/test/oldlocation")) {
|
||||||
|
response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
|
||||||
|
response.addHeader(new BasicHeader("Location", "relativelocation"));
|
||||||
|
} else if (uri.equals("/test/relativelocation")) {
|
||||||
|
response.setStatusLine(ver, HttpStatus.SC_OK);
|
||||||
|
StringEntity entity = new StringEntity("Successful redirect");
|
||||||
|
response.setEntity(entity);
|
||||||
|
} else {
|
||||||
|
response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class BogusRedirectService implements HttpRequestHandler {
|
private class BogusRedirectService implements HttpRequestHandler {
|
||||||
private String url;
|
private String url;
|
||||||
|
@ -490,6 +515,36 @@ public class TestRedirects extends ServerTestBase {
|
||||||
assertEquals(port, targetHost.getPort());
|
assertEquals(port, targetHost.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRelativeRedirect2() throws Exception {
|
||||||
|
int port = this.localServer.getServicePort();
|
||||||
|
String host = "localhost";
|
||||||
|
this.localServer.register("*", new RelativeRedirectService2());
|
||||||
|
|
||||||
|
DefaultHttpClient client = new DefaultHttpClient();
|
||||||
|
HttpContext context = client.getDefaultContext();
|
||||||
|
|
||||||
|
client.getParams().setBooleanParameter(
|
||||||
|
ClientPNames.REJECT_RELATIVE_REDIRECT, false);
|
||||||
|
HttpGet httpget = new HttpGet("/test/oldlocation");
|
||||||
|
|
||||||
|
RoutedRequest request = new RoutedRequest.Impl(httpget, getDefaultRoute());
|
||||||
|
HttpResponse response = client.execute(request, context);
|
||||||
|
HttpEntity e = response.getEntity();
|
||||||
|
if (e != null) {
|
||||||
|
e.consumeContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest reqWrapper = (HttpRequest) context.getAttribute(
|
||||||
|
ExecutionContext.HTTP_REQUEST);
|
||||||
|
HttpHost targetHost = (HttpHost) context.getAttribute(
|
||||||
|
ExecutionContext.HTTP_TARGET_HOST);
|
||||||
|
|
||||||
|
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||||
|
assertEquals("/test/relativelocation", reqWrapper.getRequestLine().getUri());
|
||||||
|
assertEquals(host, targetHost.getHostName());
|
||||||
|
assertEquals(port, targetHost.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
public void testRejectRelativeRedirect() throws Exception {
|
public void testRejectRelativeRedirect() throws Exception {
|
||||||
this.localServer.register("*", new RelativeRedirectService());
|
this.localServer.register("*", new RelativeRedirectService());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue