Return-Path: X-Original-To: apmail-hc-commits-archive@www.apache.org Delivered-To: apmail-hc-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4B0A2E1BF for ; Wed, 29 May 2013 09:05:22 +0000 (UTC) Received: (qmail 86350 invoked by uid 500); 29 May 2013 09:05:22 -0000 Delivered-To: apmail-hc-commits-archive@hc.apache.org Received: (qmail 86211 invoked by uid 500); 29 May 2013 09:05:18 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 86181 invoked by uid 99); 29 May 2013 09:05:17 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 29 May 2013 09:05:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 29 May 2013 09:05:15 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 80CC223889DE for ; Wed, 29 May 2013 09:04:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1487413 - in /httpcomponents/httpclient/trunk: ./ httpclient/src/main/java/org/apache/http/client/utils/ httpclient/src/test/java/org/apache/http/client/utils/ httpclient/src/test/java/org/apache/http/impl/client/integration/ src/docbkx/ Date: Wed, 29 May 2013 09:04:55 -0000 To: commits@hc.apache.org From: olegk@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130529090455.80CC223889DE@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: olegk Date: Wed May 29 09:04:54 2013 New Revision: 1487413 URL: http://svn.apache.org/r1487413 Log: HTTPCLIENT-1351: Added utility method to resolve final location from original request, target host and a list of redirects Contributed by James Leigh Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java (contents, props changed) httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java (contents, props changed) httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java (contents, props changed) httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml (contents, props changed) Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=1487413&r1=1487412&r2=1487413&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original) +++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Wed May 29 09:04:54 2013 @@ -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 -* [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 * [HTTPCLIENT-1344] Userinfo credentials in URI should not default to preemptive BASIC Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java?rev=1487413&r1=1487412&r2=1487413&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java (original) +++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java Wed May 29 09:04:54 2013 @@ -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; @@ -350,6 +352,52 @@ public class URIUtils { } /** + * 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 null if not available. + * @param redirects + * collection of redirect locations since the original request + * or null if not available. + * @return interpreted (absolute) URI + */ + public static URI resolve( + final URI originalURI, + final HttpHost target, + final List 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. */ private URIUtils() { Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java ------------------------------------------------------------------------------ svn:executable = * Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java?rev=1487413&r1=1487412&r2=1487413&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java (original) +++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java Wed May 29 09:04:54 2013 @@ -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); + } + } Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java ------------------------------------------------------------------------------ svn:executable = * Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java?rev=1487413&r1=1487412&r2=1487413&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java (original) +++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java Wed May 29 09:04:54 2013 @@ -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 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); } } Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java ------------------------------------------------------------------------------ svn:executable = * Modified: httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml?rev=1487413&r1=1487412&r2=1487413&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml (original) +++ httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml Wed May 29 09:04:54 2013 @@ -206,6 +206,23 @@ System.out.println("Target host: " + tar System.out.println("Final request URI: " + req.getURI()); // relative URI (no proxy used) System.out.println("Final request method: " + req.getMethod()); ]]> + 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. +
Compressed response content Propchange: httpcomponents/httpclient/trunk/src/docbkx/httpagent.xml ------------------------------------------------------------------------------ svn:executable = *