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:
Oleg Kalnichevski 2007-10-29 13:57:15 +00:00
parent e445d72146
commit 243769a600
3 changed files with 89 additions and 23 deletions

View File

@ -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>

View File

@ -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);
} }

View File

@ -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());