View Javadoc

1   // ========================================================================
2   // Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses.
12  // ========================================================================
13  
14  package org.eclipse.jetty.client;
15  
16  import java.io.IOException;
17  
18  import org.eclipse.jetty.http.HttpHeaders;
19  import org.eclipse.jetty.http.HttpSchemes;
20  import org.eclipse.jetty.http.HttpStatus;
21  import org.eclipse.jetty.io.Buffer;
22  
23  /**
24   * RedirectListener
25   *
26   * Detect and handle the redirect responses
27   */
28  public class RedirectListener extends HttpEventListenerWrapper
29  {
30      private final HttpExchange _exchange;
31      private HttpDestination _destination;
32      private String _location;
33      private int _attempts;
34      private boolean _requestComplete;
35      private boolean _responseComplete;
36      private boolean _redirected;
37  
38      public RedirectListener(HttpDestination destination, HttpExchange ex)
39      {
40          // Start of sending events through to the wrapped listener
41          // Next decision point is the onResponseStatus
42          super(ex.getEventListener(),true);
43  
44          _destination = destination;
45          _exchange = ex;
46      }
47  
48      @Override
49      public void onResponseStatus( Buffer version, int status, Buffer reason )
50          throws IOException
51      {
52          _redirected = ((status == HttpStatus.MOVED_PERMANENTLY_301 ||
53                          status == HttpStatus.MOVED_TEMPORARILY_302) &&
54                         _attempts < _destination.getHttpClient().maxRedirects());
55  
56          if (_redirected)
57          {
58              setDelegatingRequests(false);
59              setDelegatingResponses(false);
60          }
61  
62          super.onResponseStatus(version,status,reason);
63      }
64  
65  
66      @Override
67      public void onResponseHeader( Buffer name, Buffer value )
68          throws IOException
69      {
70          if (_redirected)
71          {
72              int header = HttpHeaders.CACHE.getOrdinal(name);
73              switch (header)
74              {
75                  case HttpHeaders.LOCATION_ORDINAL:
76                      _location = value.toString();
77                      break;
78              }
79          }
80          super.onResponseHeader(name,value);
81      }
82  
83      @Override
84      public void onRequestComplete() throws IOException
85      {
86          _requestComplete = true;
87  
88          if (checkExchangeComplete())
89          {
90              super.onRequestComplete();
91          }
92      }
93  
94      @Override
95      public void onResponseComplete() throws IOException
96      {
97          _responseComplete = true;
98  
99          if (checkExchangeComplete())
100         {
101             super.onResponseComplete();
102         }
103     }
104 
105     public boolean checkExchangeComplete()
106         throws IOException
107     {
108         if (_redirected && _requestComplete && _responseComplete)
109         {
110             if (_location != null)
111             {
112                 if (_location.indexOf("://")>0)
113                     _exchange.setURL(_location);
114                 else
115                     _exchange.setURI(_location);
116 
117                 // destination may have changed
118                 HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme())));
119                 
120                 if (_destination==destination)
121                     _destination.resend(_exchange);
122                 else
123                 {
124                     // unwrap to find ultimate listener.
125                     HttpEventListener listener=this;
126                     while(listener instanceof HttpEventListenerWrapper)
127                         listener=((HttpEventListenerWrapper)listener).getEventListener();
128                     //reset the listener
129                     _exchange.getEventListener().onRetry();
130                     _exchange.reset();
131                     _exchange.setEventListener(listener);
132                     destination.send(_exchange);
133                 }
134 
135                 return false;
136             }
137             else
138             {
139                 setDelegationResult(false);
140             }
141         }
142 
143         return true;
144     }
145 
146     public void onRetry()
147     {
148         _redirected=false;
149         _attempts++;
150 
151         setDelegatingRequests(true);
152         setDelegatingResponses(true);
153 
154         _requestComplete=false;
155         _responseComplete=false;
156 
157         super.onRetry();
158     }
159 }
160