Home | History | Annotate | Download | only in client
      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 
     32 package org.apache.http.impl.client;
     33 
     34 import java.net.URI;
     35 import java.net.URISyntaxException;
     36 
     37 import org.apache.commons.logging.Log;
     38 import org.apache.commons.logging.LogFactory;
     39 import org.apache.http.Header;
     40 import org.apache.http.HttpHost;
     41 import org.apache.http.HttpRequest;
     42 import org.apache.http.HttpResponse;
     43 import org.apache.http.HttpStatus;
     44 import org.apache.http.ProtocolException;
     45 import org.apache.http.client.CircularRedirectException;
     46 import org.apache.http.client.RedirectHandler;
     47 import org.apache.http.client.params.ClientPNames;
     48 import org.apache.http.client.utils.URIUtils;
     49 import org.apache.http.params.HttpParams;
     50 import org.apache.http.protocol.HttpContext;
     51 import 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
     70 public 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