From 26ee6689f3019aac7e784c93c6d14a78acff70e6 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Tue, 28 May 2013 15:08:31 +0000 Subject: [PATCH] HTTPCLIENT-1351: added method to HttpClientContext to obtain redirect locations git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1486956 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/http/client/URICollection.java | 51 +++++++++++++++++++ .../client/protocol/HttpClientContext.java | 24 ++++----- .../impl/client/DefaultRedirectStrategy.java | 8 ++- .../http/impl/client/RedirectLocations.java | 31 ++++++++++- .../http/impl/execchain/ProtocolExec.java | 6 +-- .../TestClientRequestExecution.java | 3 -- .../client/integration/TestRedirects.java | 13 +++++ 7 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 httpclient/src/main/java/org/apache/http/client/URICollection.java diff --git a/httpclient/src/main/java/org/apache/http/client/URICollection.java b/httpclient/src/main/java/org/apache/http/client/URICollection.java new file mode 100644 index 000000000..6cd72c358 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/client/URICollection.java @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.net.URI; +import java.util.List; +import java.util.Set; + +/** + * This class represents an iterable collection of {@link java.net.URI} locations. + * + * @since 4.3 + */ +public interface URICollection extends Iterable { + + int getCount(); + + boolean isEmpty(); + + boolean contains(URI uri); + + Set getUnique(); + + List getAll(); + +} diff --git a/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java b/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java index 00af67f3d..b7751d231 100644 --- a/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java +++ b/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java @@ -27,14 +27,13 @@ package org.apache.http.client.protocol; -import java.net.URI; - import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthState; import org.apache.http.client.AuthCache; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.URICollection; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Lookup; import org.apache.http.conn.routing.HttpRoute; @@ -56,18 +55,19 @@ import org.apache.http.protocol.HttpCoreContext; @NotThreadSafe public class HttpClientContext extends HttpCoreContext { - /** - * Attribute name of a {@link URI} object that represents - * request URI location (relative or absolute) of the last request target. - */ - public static final String HTTP_LOCATION = "http.location"; - /** * Attribute name of a {@link org.apache.http.conn.routing.RouteInfo} * object that represents the actual connection route. */ public static final String HTTP_ROUTE = "http.route"; + /** + * Attribute name of a {@link org.apache.http.client.URICollection} object that + * represents a collection of all redirect locations received in the process + * of request execution. + */ + public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; + /** * Attribute name of a {@link org.apache.http.config.Lookup} object that represents * the actual {@link CookieSpecProvider} registry. @@ -160,14 +160,14 @@ public class HttpClientContext extends HttpCoreContext { super(); } - public URI getHttpLocation() { - return getAttribute(HTTP_LOCATION, URI.class); - } - public RouteInfo getHttpRoute() { return getAttribute(HTTP_ROUTE, HttpRoute.class); } + public URICollection getRedirectLocations() { + return getAttribute(REDIRECT_LOCATIONS, URICollection.class); + } + public CookieStore getCookieStore() { return getAttribute(COOKIE_STORE, CookieStore.class); } diff --git a/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStrategy.java b/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStrategy.java index b6ab2a4f4..9922c340a 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStrategy.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStrategy.java @@ -74,6 +74,10 @@ public class DefaultRedirectStrategy implements RedirectStrategy { private final Log log = LogFactory.getLog(getClass()); + /** + * @deprecated (4.3) use {@link org.apache.http.client.protocol.HttpClientContext#REDIRECT_LOCATIONS}. + */ + @Deprecated public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; public static final DefaultRedirectStrategy INSTANCE = new DefaultRedirectStrategy(); @@ -160,10 +164,10 @@ public class DefaultRedirectStrategy implements RedirectStrategy { } RedirectLocations redirectLocations = (RedirectLocations) clientContext.getAttribute( - REDIRECT_LOCATIONS); + HttpClientContext.REDIRECT_LOCATIONS); if (redirectLocations == null) { redirectLocations = new RedirectLocations(); - context.setAttribute(REDIRECT_LOCATIONS, redirectLocations); + context.setAttribute(HttpClientContext.REDIRECT_LOCATIONS, redirectLocations); } if (!config.isCircularRedirectsAllowed()) { if (redirectLocations.contains(uri)) { diff --git a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java index c8d77a8b6..726ce4f5a 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Set; import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.client.URICollection; /** * This class represents a collection of {@link URI}s used as redirect locations. @@ -42,7 +43,7 @@ import org.apache.http.annotation.NotThreadSafe; * @since 4.0 */ @NotThreadSafe // HashSet is not synch. -public class RedirectLocations { +public class RedirectLocations implements URICollection { private final Set unique; private final List all; @@ -96,4 +97,32 @@ public class RedirectLocations { return new ArrayList(this.all); } + /** + * @since 4.3 + */ + public Set getUnique() { + return new HashSet(this.unique); + } + + /** + * @since 4.3 + */ + public Iterator iterator() { + return getAll().iterator(); + } + + /** + * @since 4.3 + */ + public int getCount() { + return this.all.size(); + } + + /** + * @since 4.3 + */ + public boolean isEmpty() { + return this.all.isEmpty(); + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.java b/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.java index a4d940ad9..3315cef1a 100644 --- a/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.java +++ b/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.java @@ -74,12 +74,10 @@ public class ProtocolExec implements ClientExecChain { private void rewriteRequestURI( final HttpRequestWrapper request, - final HttpRoute route, - final HttpClientContext context) throws ProtocolException { + final HttpRoute route) throws ProtocolException { try { URI uri = request.getURI(); if (uri != null) { - context.setAttribute(HttpClientContext.HTTP_LOCATION, uri); if (route.getProxyHost() != null && !route.isTunnelled()) { // Make sure the request URI is absolute if (!uri.isAbsolute()) { @@ -129,7 +127,7 @@ public class ProtocolExec implements ClientExecChain { request.setURI(uri); // Re-write request URI if needed - rewriteRequestURI(request, route, context); + rewriteRequestURI(request, route); final HttpParams params = request.getParams(); HttpHost virtualHost = (HttpHost) params.getParameter(ClientPNames.VIRTUAL_HOST); diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java index f56572465..e1300774e 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java @@ -258,9 +258,6 @@ public class TestClientRequestExecution extends IntegrationTestBase { final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST); Assert.assertEquals("/stuff", request.getRequestLine().getUri()); - - final URI location = (URI) context.getAttribute(HttpClientContext.HTTP_LOCATION); - Assert.assertEquals(uri, location); } } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java index 2d5d08a4d..cd75902fa 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java @@ -27,6 +27,7 @@ package org.apache.http.impl.client.integration; import java.io.IOException; +import java.net.URI; import java.util.Arrays; import org.apache.http.Header; @@ -41,10 +42,12 @@ import org.apache.http.client.CircularRedirectException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.RedirectException; +import org.apache.http.client.URICollection; import org.apache.http.client.config.RequestConfig; 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.URIUtils; import org.apache.http.cookie.SM; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCookieStore; @@ -222,6 +225,9 @@ public class TestRedirects extends IntegrationTestBase { Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); + + URICollection redirects = context.getRedirectLocations(); + Assert.assertNull(redirects); } @Test @@ -243,6 +249,13 @@ public class TestRedirects extends IntegrationTestBase { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); + + URICollection redirects = context.getRedirectLocations(); + Assert.assertNotNull(redirects); + Assert.assertEquals(1, redirects.getCount()); + + URI redirect = URIUtils.rewriteURI(new URI("/newlocation/"), target); + Assert.assertTrue(redirects.contains(redirect)); } @Test