View Javadoc
1   package org.esigate.impl;
2   
3   import java.net.URI;
4   
5   import org.apache.commons.lang3.StringUtils;
6   import org.apache.http.HttpRequest;
7   import org.apache.http.HttpResponse;
8   import org.apache.http.HttpStatus;
9   import org.apache.http.ProtocolException;
10  import org.apache.http.client.methods.HttpGet;
11  import org.apache.http.client.methods.HttpHead;
12  import org.apache.http.client.methods.HttpUriRequest;
13  import org.apache.http.client.methods.RequestBuilder;
14  import org.apache.http.impl.client.DefaultRedirectStrategy;
15  import org.apache.http.protocol.HttpContext;
16  import org.esigate.api.RedirectStrategy2;
17  import org.esigate.http.OutgoingRequest;
18  import org.esigate.http.ResourceUtils;
19  import org.esigate.util.UriUtils;
20  
21  /**
22   * The redirect strategy for fetching fragments.
23   * 
24   * <p>
25   * This strategy is based on {@link DefaultRedirectStrategy} but differs for local redirections:
26   * 
27   * <p>
28   * If a local (same provider) redirection is detected, the URI is returned as relative. This ensure that a public
29   * (visible) url is not used instead of the provider url for the next requests.
30   * 
31   * @author Nicolas Richeton
32   * 
33   */
34  public class FragmentRedirectStrategy implements RedirectStrategy2 {
35      private final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
36  
37      /**
38       * @see DefaultRedirectStrategy#isRedirected(HttpRequest, HttpResponse, HttpContext)
39       */
40      @Override
41      public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
42              throws ProtocolException {
43          return this.redirectStrategy.isRedirected(request, response, context);
44      }
45  
46      /**
47       * @see DefaultRedirectStrategy#getRedirect(HttpRequest, HttpResponse, HttpContext)
48       */
49      @Override
50      public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context)
51              throws ProtocolException {
52  
53          // Code from DefaultRedirectStrategy
54          // To ensure usage of the local getLocationURI implementation.
55  
56          final URI uri = getLocationURI(request, response, context);
57          final String method = request.getRequestLine().getMethod();
58          if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
59              return new HttpHead(uri);
60          } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
61              return new HttpGet(uri);
62          } else {
63              final int status = response.getStatusLine().getStatusCode();
64              if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
65                  return RequestBuilder.copy(request).setUri(uri).build();
66              } else {
67                  return new HttpGet(uri);
68              }
69          }
70      }
71  
72      /**
73       * For local redirects, converts to relative urls.
74       * 
75       * @param request
76       *            must be an {@link OutgoingRequest}.
77       */
78      @Override
79      public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
80          URI uri = this.redirectStrategy.getLocationURI(request, response, context);
81  
82          String resultingPageUrl = uri.toString();
83  
84          DriverRequest driverRequest = ((OutgoingRequest) request).getOriginalRequest();
85  
86          // Remove context if present
87          if (StringUtils.startsWith(resultingPageUrl, driverRequest.getVisibleBaseUrl())) {
88              resultingPageUrl =
89                      "/"
90                              + StringUtils.stripStart(
91                                      StringUtils.replace(resultingPageUrl, driverRequest.getVisibleBaseUrl(), ""), "/");
92          }
93          resultingPageUrl = ResourceUtils.getHttpUrlWithQueryString(resultingPageUrl, driverRequest, false);
94  
95          return UriUtils.createURI(ResourceUtils.getHttpUrlWithQueryString(resultingPageUrl, driverRequest, false));
96      }
97  
98  }