1
2
3
4
5
6
7
8
9
10
11
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
25
26
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
41
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 {
114 _exchange.setURL(_location);
115 }
116 else
117 {
118 _exchange.setRequestURI(_location);
119 }
120
121
122 boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme()));
123 HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),isHttps);
124
125 if (_destination==destination)
126 {
127 _destination.resend(_exchange);
128 }
129 else
130 {
131
132 HttpEventListener listener=this;
133 while(listener instanceof HttpEventListenerWrapper)
134 {
135 listener=((HttpEventListenerWrapper)listener).getEventListener();
136 }
137
138
139 _exchange.getEventListener().onRetry();
140 _exchange.reset();
141 _exchange.setEventListener(listener);
142
143
144 Address address = _exchange.getAddress();
145 int port = address.getPort();
146 StringBuilder hostHeader = new StringBuilder( 64 );
147 hostHeader.append( address.getHost() );
148 if( !( ( port == 80 && !isHttps ) || ( port == 443 && isHttps ) ) )
149 {
150 hostHeader.append( ':' );
151 hostHeader.append( port );
152 }
153
154 _exchange.setRequestHeader( HttpHeaders.HOST, hostHeader.toString() );
155
156 destination.send(_exchange);
157 }
158
159 return false;
160 }
161 else
162 {
163 setDelegationResult(false);
164 }
165 }
166
167 return true;
168 }
169
170 public void onRetry()
171 {
172 _redirected=false;
173 _attempts++;
174
175 setDelegatingRequests(true);
176 setDelegatingResponses(true);
177
178 _requestComplete=false;
179 _responseComplete=false;
180
181 super.onRetry();
182 }
183
184
185
186
187 @Override
188 public void onConnectionFailed( Throwable ex )
189 {
190 setDelegatingRequests(true);
191 setDelegatingResponses(true);
192
193 super.onConnectionFailed( ex );
194 }
195
196
197
198
199 @Override
200 public void onException( Throwable ex )
201 {
202 setDelegatingRequests(true);
203 setDelegatingResponses(true);
204
205 super.onException( ex );
206 }
207 }