1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client;
20
21 import java.io.IOException;
22
23 import org.eclipse.jetty.http.HttpHeaders;
24 import org.eclipse.jetty.http.HttpSchemes;
25 import org.eclipse.jetty.http.HttpStatus;
26 import org.eclipse.jetty.io.Buffer;
27
28
29
30
31
32
33 public class RedirectListener extends HttpEventListenerWrapper
34 {
35 private final HttpExchange _exchange;
36 private HttpDestination _destination;
37 private String _location;
38 private int _attempts;
39 private boolean _requestComplete;
40 private boolean _responseComplete;
41 private boolean _redirected;
42
43 public RedirectListener(HttpDestination destination, HttpExchange ex)
44 {
45
46
47 super(ex.getEventListener(),true);
48
49 _destination = destination;
50 _exchange = ex;
51 }
52
53 @Override
54 public void onResponseStatus( Buffer version, int status, Buffer reason )
55 throws IOException
56 {
57 _redirected = ((status == HttpStatus.MOVED_PERMANENTLY_301 ||
58 status == HttpStatus.MOVED_TEMPORARILY_302) &&
59 _attempts < _destination.getHttpClient().maxRedirects());
60
61 if (_redirected)
62 {
63 setDelegatingRequests(false);
64 setDelegatingResponses(false);
65 }
66
67 super.onResponseStatus(version,status,reason);
68 }
69
70
71 @Override
72 public void onResponseHeader( Buffer name, Buffer value )
73 throws IOException
74 {
75 if (_redirected)
76 {
77 int header = HttpHeaders.CACHE.getOrdinal(name);
78 switch (header)
79 {
80 case HttpHeaders.LOCATION_ORDINAL:
81 _location = value.toString();
82 break;
83 }
84 }
85 super.onResponseHeader(name,value);
86 }
87
88 @Override
89 public void onRequestComplete() throws IOException
90 {
91 _requestComplete = true;
92
93 if (checkExchangeComplete())
94 {
95 super.onRequestComplete();
96 }
97 }
98
99 @Override
100 public void onResponseComplete() throws IOException
101 {
102 _responseComplete = true;
103
104 if (checkExchangeComplete())
105 {
106 super.onResponseComplete();
107 }
108 }
109
110 public boolean checkExchangeComplete()
111 throws IOException
112 {
113 if (_redirected && _requestComplete && _responseComplete)
114 {
115 if (_location != null)
116 {
117 if (_location.indexOf("://")>0)
118 {
119 _exchange.setURL(_location);
120 }
121 else
122 {
123 _exchange.setRequestURI(_location);
124 }
125
126
127 boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme()));
128 HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),isHttps);
129
130 if (_destination==destination)
131 {
132 _destination.resend(_exchange);
133 }
134 else
135 {
136
137 HttpEventListener listener=this;
138 while(listener instanceof HttpEventListenerWrapper)
139 {
140 listener=((HttpEventListenerWrapper)listener).getEventListener();
141 }
142
143
144 _exchange.getEventListener().onRetry();
145 _exchange.reset();
146 _exchange.setEventListener(listener);
147
148
149 Address address = _exchange.getAddress();
150 int port = address.getPort();
151 StringBuilder hostHeader = new StringBuilder( 64 );
152 hostHeader.append( address.getHost() );
153 if( !( ( port == 80 && !isHttps ) || ( port == 443 && isHttps ) ) )
154 {
155 hostHeader.append( ':' );
156 hostHeader.append( port );
157 }
158
159 _exchange.setRequestHeader( HttpHeaders.HOST, hostHeader.toString() );
160
161 destination.send(_exchange);
162 }
163
164 return false;
165 }
166 else
167 {
168 setDelegationResult(false);
169 }
170 }
171
172 return true;
173 }
174
175 public void onRetry()
176 {
177 _redirected=false;
178 _attempts++;
179
180 setDelegatingRequests(true);
181 setDelegatingResponses(true);
182
183 _requestComplete=false;
184 _responseComplete=false;
185
186 super.onRetry();
187 }
188
189
190
191
192 @Override
193 public void onConnectionFailed( Throwable ex )
194 {
195 setDelegatingRequests(true);
196 setDelegatingResponses(true);
197
198 super.onConnectionFailed( ex );
199 }
200
201
202
203
204 @Override
205 public void onException( Throwable ex )
206 {
207 setDelegatingRequests(true);
208 setDelegatingResponses(true);
209
210 super.onException( ex );
211 }
212 }