DefaultRedirectHandler.java revision d42abb2fd917184764daf22f5f299e848b8701d7
1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultRedirectHandler.java $
3 * $Revision: 673450 $
4 * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $
5 *
6 * ====================================================================
7 * Licensed to the Apache Software Foundation (ASF) under one
8 * or more contributor license agreements.  See the NOTICE file
9 * distributed with this work for additional information
10 * regarding copyright ownership.  The ASF licenses this file
11 * to you under the Apache License, Version 2.0 (the
12 * "License"); you may not use this file except in compliance
13 * with the License.  You may obtain a copy of the License at
14 *
15 *   http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing,
18 * software distributed under the License is distributed on an
19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20 * KIND, either express or implied.  See the License for the
21 * specific language governing permissions and limitations
22 * under the License.
23 * ====================================================================
24 *
25 * This software consists of voluntary contributions made by many
26 * individuals on behalf of the Apache Software Foundation.  For more
27 * information on the Apache Software Foundation, please see
28 * <http://www.apache.org/>.
29 *
30 */
31
32package org.apache.http.impl.client;
33
34import java.net.URI;
35import java.net.URISyntaxException;
36
37import org.apache.commons.logging.Log;
38import org.apache.commons.logging.LogFactory;
39import org.apache.http.Header;
40import org.apache.http.HttpHost;
41import org.apache.http.HttpRequest;
42import org.apache.http.HttpResponse;
43import org.apache.http.HttpStatus;
44import org.apache.http.ProtocolException;
45import org.apache.http.client.CircularRedirectException;
46import org.apache.http.client.RedirectHandler;
47import org.apache.http.client.params.ClientPNames;
48import org.apache.http.client.utils.URIUtils;
49import org.apache.http.params.HttpParams;
50import org.apache.http.protocol.HttpContext;
51import org.apache.http.protocol.ExecutionContext;
52
53
54/**
55 * Default implementation of {@link RedirectHandler}.
56 *
57 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
58 *
59 *
60 * <!-- empty lines to avoid svn diff problems -->
61 * @version $Revision: 673450 $
62 *
63 * @since 4.0
64 *
65 * @deprecated Please use {@link java.net.URL#openConnection} instead.
66 *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
67 *     for further details.
68 */
69@Deprecated
70public class DefaultRedirectHandler implements RedirectHandler {
71
72    private final Log log = LogFactory.getLog(getClass());
73
74    private static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations";
75
76    public DefaultRedirectHandler() {
77        super();
78    }
79
80    public boolean isRedirectRequested(
81            final HttpResponse response,
82            final HttpContext context) {
83        if (response == null) {
84            throw new IllegalArgumentException("HTTP response may not be null");
85        }
86        int statusCode = response.getStatusLine().getStatusCode();
87        switch (statusCode) {
88        case HttpStatus.SC_MOVED_TEMPORARILY:
89        case HttpStatus.SC_MOVED_PERMANENTLY:
90        case HttpStatus.SC_SEE_OTHER:
91        case HttpStatus.SC_TEMPORARY_REDIRECT:
92            return true;
93        default:
94            return false;
95        } //end of switch
96    }
97
98    public URI getLocationURI(
99            final HttpResponse response,
100            final HttpContext context) throws ProtocolException {
101        if (response == null) {
102            throw new IllegalArgumentException("HTTP response may not be null");
103        }
104        //get the location header to find out where to redirect to
105        Header locationHeader = response.getFirstHeader("location");
106        if (locationHeader == null) {
107            // got a redirect response, but no location header
108            throw new ProtocolException(
109                    "Received redirect response " + response.getStatusLine()
110                    + " but no location header");
111        }
112        String location = locationHeader.getValue();
113        if (this.log.isDebugEnabled()) {
114            this.log.debug("Redirect requested to location '" + location + "'");
115        }
116
117        URI uri;
118        try {
119            uri = new URI(location);
120        } catch (URISyntaxException ex) {
121            throw new ProtocolException("Invalid redirect URI: " + location, ex);
122        }
123
124        HttpParams params = response.getParams();
125        // rfc2616 demands the location value be a complete URI
126        // Location       = "Location" ":" absoluteURI
127        if (!uri.isAbsolute()) {
128            if (params.isParameterTrue(ClientPNames.REJECT_RELATIVE_REDIRECT)) {
129                throw new ProtocolException("Relative redirect location '"
130                        + uri + "' not allowed");
131            }
132            // Adjust location URI
133            HttpHost target = (HttpHost) context.getAttribute(
134                    ExecutionContext.HTTP_TARGET_HOST);
135            if (target == null) {
136                throw new IllegalStateException("Target host not available " +
137                        "in the HTTP context");
138            }
139
140            HttpRequest request = (HttpRequest) context.getAttribute(
141                    ExecutionContext.HTTP_REQUEST);
142
143            try {
144                URI requestURI = new URI(request.getRequestLine().getUri());
145                URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, true);
146                uri = URIUtils.resolve(absoluteRequestURI, uri);
147            } catch (URISyntaxException ex) {
148                throw new ProtocolException(ex.getMessage(), ex);
149            }
150        }
151
152        if (params.isParameterFalse(ClientPNames.ALLOW_CIRCULAR_REDIRECTS)) {
153
154            RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute(
155                    REDIRECT_LOCATIONS);
156
157            if (redirectLocations == null) {
158                redirectLocations = new RedirectLocations();
159                context.setAttribute(REDIRECT_LOCATIONS, redirectLocations);
160            }
161
162            URI redirectURI;
163            if (uri.getFragment() != null) {
164                try {
165                    HttpHost target = new HttpHost(
166                            uri.getHost(),
167                            uri.getPort(),
168                            uri.getScheme());
169                    redirectURI = URIUtils.rewriteURI(uri, target, true);
170                } catch (URISyntaxException ex) {
171                    throw new ProtocolException(ex.getMessage(), ex);
172                }
173            } else {
174                redirectURI = uri;
175            }
176
177            if (redirectLocations.contains(redirectURI)) {
178                throw new CircularRedirectException("Circular redirect to '" +
179                        redirectURI + "'");
180            } else {
181                redirectLocations.add(redirectURI);
182            }
183        }
184
185        return uri;
186    }
187
188}
189