HTTPCLIENT-1351: Added utility method to resolve final location from original request, target host and a list of redirects
Contributed by James Leigh <james at 3roundstones.com> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1487413 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
26ee6689f3
commit
eeaec64f5c
|
@ -4,7 +4,8 @@ Changes since release 4.3 BETA1
|
|||
* [HTTPCLIENT-1354] do not quote algorithm parameter in DIGEST auth response.
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
||||
* [HTTPCLIENT-1351] Preserve last request URI in the execution context.
|
||||
* [HTTPCLIENT-1351] Added utility method to resolve final location from original request,
|
||||
target host and a list of redirects.
|
||||
Contributed by James Leigh <james at 3roundstones.com>
|
||||
|
||||
* [HTTPCLIENT-1344] Userinfo credentials in URI should not default to preemptive BASIC
|
||||
|
|
48
httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java
Normal file → Executable file
48
httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java
Normal file → Executable file
|
@ -28,11 +28,13 @@ package org.apache.http.client.utils;
|
|||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.client.URICollection;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.TextUtils;
|
||||
|
||||
|
@ -349,6 +351,52 @@ public class URIUtils {
|
|||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives the interpreted (absolute) URI that was used to generate the last
|
||||
* request. This is done by extracting the request-uri and target origin for
|
||||
* the last request and scanning all the redirect locations for the last
|
||||
* fragment identifier, then combining the result into a {@link URI}.
|
||||
*
|
||||
* @param originalURI
|
||||
* original request before any redirects
|
||||
* @param target
|
||||
* if the last URI is relative, it is resolved against this target,
|
||||
* or <code>null</code> if not available.
|
||||
* @param redirects
|
||||
* collection of redirect locations since the original request
|
||||
* or <code>null</code> if not available.
|
||||
* @return interpreted (absolute) URI
|
||||
*/
|
||||
public static URI resolve(
|
||||
final URI originalURI,
|
||||
final HttpHost target,
|
||||
final List<URI> redirects) throws URISyntaxException {
|
||||
Args.notNull(originalURI, "Request URI");
|
||||
final URIBuilder uribuilder;
|
||||
if (redirects == null || redirects.isEmpty()) {
|
||||
uribuilder = new URIBuilder(originalURI);
|
||||
} else {
|
||||
uribuilder = new URIBuilder(redirects.get(redirects.size() - 1));
|
||||
String frag = uribuilder.getFragment();
|
||||
// read interpreted fragment identifier from redirect locations
|
||||
for (int i = redirects.size() - 1; frag == null && i >= 0; i--) {
|
||||
frag = redirects.get(i).getFragment();
|
||||
}
|
||||
uribuilder.setFragment(frag);
|
||||
}
|
||||
// read interpreted fragment identifier from original request
|
||||
if (uribuilder.getFragment() == null) {
|
||||
uribuilder.setFragment(originalURI.getFragment());
|
||||
}
|
||||
// last target origin
|
||||
if (target != null && !uribuilder.isAbsolute()) {
|
||||
uribuilder.setScheme(target.getSchemeName());
|
||||
uribuilder.setHost(target.getHostName());
|
||||
uribuilder.setPort(target.getPort());
|
||||
}
|
||||
return uribuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
|
|
75
httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java
Normal file → Executable file
75
httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java
Normal file → Executable file
|
@ -27,8 +27,19 @@
|
|||
package org.apache.http.client.utils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.protocol.HttpCoreContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -203,4 +214,68 @@ public class TestURIUtils {
|
|||
URIUtils.extractHost(new URI("http://localhost:;sessionid=stuff/abcd")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpLocationWithRelativeFragment() throws Exception {
|
||||
final HttpHost target = new HttpHost("localhost", -1, "http");
|
||||
final URI requestURI = new URI("/stuff#blahblah");
|
||||
|
||||
final URI location = URIUtils.resolve(requestURI, target, null);
|
||||
final URI expectedURI = new URIBuilder(requestURI)
|
||||
.setHost(target.getHostName())
|
||||
.setScheme(target.getSchemeName())
|
||||
.build();
|
||||
Assert.assertEquals(expectedURI, location);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpLocationWithAbsoluteFragment() throws Exception {
|
||||
final HttpHost target = new HttpHost("localhost", 80, "http");
|
||||
|
||||
final URI requestURI = new URIBuilder()
|
||||
.setHost(target.getHostName())
|
||||
.setScheme(target.getSchemeName())
|
||||
.setPath("/stuff")
|
||||
.setFragment("blahblah")
|
||||
.build();
|
||||
|
||||
final URI location = URIUtils.resolve(requestURI, target, null);
|
||||
final URI expectedURI = requestURI;
|
||||
Assert.assertEquals(expectedURI, location);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpLocationRedirect() throws Exception {
|
||||
final HttpHost target = new HttpHost("localhost", -1, "http");
|
||||
final URI requestURI = new URI("/People.htm#tim");
|
||||
|
||||
final URI redirect = new URI("http://localhost/people.html");
|
||||
|
||||
final URI location = URIUtils.resolve(requestURI, target, Arrays.asList(redirect));
|
||||
final URI expectedURI = new URIBuilder()
|
||||
.setHost(target.getHostName())
|
||||
.setScheme(target.getSchemeName())
|
||||
.setPath("/people.html")
|
||||
.setFragment("tim")
|
||||
.build();
|
||||
Assert.assertEquals(expectedURI, location);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpLocationWithRedirectFragment() throws Exception {
|
||||
final HttpHost target = new HttpHost("localhost", -1, "http");
|
||||
final URI requestURI = new URI("/~tim");
|
||||
|
||||
final URI redirect1 = new URI("http://localhost/People.htm#tim");
|
||||
final URI redirect2 = new URI("http://localhost/people.html");
|
||||
|
||||
final URI location = URIUtils.resolve(requestURI, target, Arrays.asList(redirect1, redirect2));
|
||||
final URI expectedURI = new URIBuilder()
|
||||
.setHost(target.getHostName())
|
||||
.setScheme(target.getSchemeName())
|
||||
.setPath("/people.html")
|
||||
.setFragment("tim")
|
||||
.build();
|
||||
Assert.assertEquals(expectedURI, location);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
9
httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java
Normal file → Executable file
9
httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java
Normal file → Executable file
|
@ -41,10 +41,12 @@ import org.apache.http.HttpStatus;
|
|||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpRequestRetryHandler;
|
||||
import org.apache.http.client.NonRepeatableRequestException;
|
||||
import org.apache.http.client.URICollection;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.client.utils.URIUtils;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
@ -256,8 +258,13 @@ public class TestClientRequestExecution extends IntegrationTestBase {
|
|||
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
EntityUtils.consume(response.getEntity());
|
||||
|
||||
final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
|
||||
final HttpRequest request = context.getRequest();
|
||||
Assert.assertEquals("/stuff", request.getRequestLine().getUri());
|
||||
|
||||
final URICollection redirectLocations = context.getRedirectLocations();
|
||||
final URI location = URIUtils.resolve(uri, target,
|
||||
redirectLocations != null ? redirectLocations.getAll() : null);
|
||||
Assert.assertEquals(uri, location);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -205,6 +205,23 @@ HttpUriRequest req = (HttpUriRequest) localContext.getAttribute(
|
|||
System.out.println("Target host: " + target);
|
||||
System.out.println("Final request URI: " + req.getURI()); // relative URI (no proxy used)
|
||||
System.out.println("Final request method: " + req.getMethod());
|
||||
]]></programlisting>
|
||||
<para>The final interpreted absolute HTTP location can be built using the original request
|
||||
and the context. The utility method URIUtils.resolve(URI,HttpHost,URICollection)
|
||||
can be used to build the interpreted absolute URI used to generate the final request.
|
||||
This method includes the last fragment identifier from the redirect requests or
|
||||
the original request.</para>
|
||||
<programlisting><![CDATA[
|
||||
DefaultHttpClient httpclient = new DefaultHttpClient();
|
||||
|
||||
HttpClientContext context = HttpClientContext.create();
|
||||
HttpGet httpget = new HttpGet("http://localhost:8080/");
|
||||
HttpResponse response = httpclient.execute(httpget, context);
|
||||
HttpHost target = context.getTargetHost();
|
||||
URICollection redirectLocations = context.getRedirectLocations();
|
||||
URI location = URIUtils.resolve(httpget.getURI(), target,
|
||||
redirectLocations != null ? redirectLocations.getAll() : null);
|
||||
System.out.println("Final HTTP location: " + location.toASCIIString()); // absolute URI
|
||||
]]></programlisting>
|
||||
</section>
|
||||
<section>
|
||||
|
|
Loading…
Reference in New Issue