@@ -987,13 +987,16 @@ private <T> ListenableFuture<T> doConnect(final Request request, final AsyncHand
987
987
remoteAddress = new InetSocketAddress (request .getInetAddress (), AsyncHttpProviderUtils .getPort (uri ));
988
988
} else if (proxyServer == null || avoidProxy ) {
989
989
remoteAddress = new InetSocketAddress (AsyncHttpProviderUtils .getHost (uri ), AsyncHttpProviderUtils .getPort (uri ));
990
- } else if (request .getLocalAddress () != null ) {
991
- remoteAddress = new InetSocketAddress (request .getLocalAddress (), 0 );
992
990
} else {
993
991
remoteAddress = new InetSocketAddress (proxyServer .getHost (), proxyServer .getPort ());
994
992
}
995
993
996
- channelFuture = bootstrap .connect (remoteAddress );
994
+ if (request .getLocalAddress () != null ){
995
+ channelFuture = bootstrap .connect (remoteAddress , new InetSocketAddress (request .getLocalAddress (), 0 ));
996
+ }else {
997
+ channelFuture = bootstrap .connect (remoteAddress );
998
+ }
999
+
997
1000
} catch (Throwable t ) {
998
1001
if (acquiredConnection ) {
999
1002
freeConnections .release ();
@@ -1966,6 +1969,81 @@ private static final boolean validateWebSocketRequest(Request request, AsyncHand
1966
1969
return true ;
1967
1970
}
1968
1971
1972
+ private boolean redirect (Request request ,
1973
+ NettyResponseFuture <?> future ,
1974
+ HttpResponse response ,
1975
+ final ChannelHandlerContext ctx ) throws Exception {
1976
+
1977
+ int statusCode = response .getStatus ().getCode ();
1978
+ boolean redirectEnabled = request .isRedirectOverrideSet () ? request .isRedirectEnabled () : config .isRedirectEnabled ();
1979
+ if (redirectEnabled && (statusCode == 302
1980
+ || statusCode == 301
1981
+ || statusCode == 303
1982
+ || statusCode == 307 )) {
1983
+
1984
+ if (future .incrementAndGetCurrentRedirectCount () < config .getMaxRedirects ()) {
1985
+ // We must allow 401 handling again.
1986
+ future .getAndSetAuth (false );
1987
+
1988
+ String location = response .getHeader (HttpHeaders .Names .LOCATION );
1989
+ URI uri = AsyncHttpProviderUtils .getRedirectUri (future .getURI (), location );
1990
+ boolean stripQueryString = config .isRemoveQueryParamOnRedirect ();
1991
+ if (!uri .toString ().equalsIgnoreCase (future .getURI ().toString ())) {
1992
+ final RequestBuilder nBuilder = stripQueryString ?
1993
+ new RequestBuilder (future .getRequest ()).setQueryParameters (null )
1994
+ : new RequestBuilder (future .getRequest ());
1995
+
1996
+ if (!(statusCode < 302 || statusCode > 303 )
1997
+ && !(statusCode == 302
1998
+ && config .isStrict302Handling ())) {
1999
+ nBuilder .setMethod ("GET" );
2000
+ }
2001
+ final URI initialConnectionUri = future .getURI ();
2002
+ final boolean initialConnectionKeepAlive = future .getKeepAlive ();
2003
+ future .setURI (uri );
2004
+ String newUrl = uri .toString ();
2005
+ if (request .getUrl ().startsWith (WEBSOCKET )) {
2006
+ newUrl = newUrl .replace (HTTP , WEBSOCKET );
2007
+ }
2008
+
2009
+ log .debug ("Redirecting to {}" , newUrl );
2010
+ for (String cookieStr : future .getHttpResponse ().getHeaders (HttpHeaders .Names .SET_COOKIE )) {
2011
+ Cookie c = AsyncHttpProviderUtils .parseCookie (cookieStr );
2012
+ nBuilder .addOrReplaceCookie (c );
2013
+ }
2014
+
2015
+ for (String cookieStr : future .getHttpResponse ().getHeaders (HttpHeaders .Names .SET_COOKIE2 )) {
2016
+ Cookie c = AsyncHttpProviderUtils .parseCookie (cookieStr );
2017
+ nBuilder .addOrReplaceCookie (c );
2018
+ }
2019
+
2020
+ AsyncCallable ac = new AsyncCallable (future ) {
2021
+ public Object call () throws Exception {
2022
+ if (initialConnectionKeepAlive && ctx .getChannel ().isReadable () &&
2023
+ connectionsPool .offer (AsyncHttpProviderUtils .getBaseUrl (initialConnectionUri ), ctx .getChannel ())) {
2024
+ return null ;
2025
+ }
2026
+ finishChannel (ctx );
2027
+ return null ;
2028
+ }
2029
+ };
2030
+
2031
+ if (response .isChunked ()) {
2032
+ // We must make sure there is no bytes left before executing the next request.
2033
+ ctx .setAttachment (ac );
2034
+ } else {
2035
+ ac .call ();
2036
+ }
2037
+ nextRequest (nBuilder .setUrl (newUrl ).build (), future );
2038
+ return true ;
2039
+ }
2040
+ } else {
2041
+ throw new MaxRedirectException ("Maximum redirect reached: " + config .getMaxRedirects ());
2042
+ }
2043
+ }
2044
+ return false ;
2045
+ }
2046
+
1969
2047
private final class HttpProtocol implements Protocol {
1970
2048
// @Override
1971
2049
public void handle (final ChannelHandlerContext ctx , final MessageEvent e ) throws Exception {
@@ -2142,69 +2220,7 @@ public Object call() throws Exception {
2142
2220
return ;
2143
2221
}
2144
2222
2145
- boolean redirectEnabled = request .isRedirectOverrideSet () ? request .isRedirectEnabled () : config .isRedirectEnabled ();
2146
- if (redirectEnabled && (statusCode == 302
2147
- || statusCode == 301
2148
- || statusCode == 303
2149
- || statusCode == 307 )) {
2150
-
2151
- if (future .incrementAndGetCurrentRedirectCount () < config .getMaxRedirects ()) {
2152
- // We must allow 401 handling again.
2153
- future .getAndSetAuth (false );
2154
-
2155
- String location = response .getHeader (HttpHeaders .Names .LOCATION );
2156
- URI uri = AsyncHttpProviderUtils .getRedirectUri (future .getURI (), location );
2157
- boolean stripQueryString = config .isRemoveQueryParamOnRedirect ();
2158
- if (!uri .toString ().equalsIgnoreCase (future .getURI ().toString ())) {
2159
- final RequestBuilder nBuilder = stripQueryString ?
2160
- new RequestBuilder (future .getRequest ()).setQueryParameters (null )
2161
- : new RequestBuilder (future .getRequest ());
2162
-
2163
- if (!(statusCode < 302 || statusCode > 303 )
2164
- && !(statusCode == 302
2165
- && config .isStrict302Handling ())) {
2166
- nBuilder .setMethod ("GET" );
2167
- }
2168
- final URI initialConnectionUri = future .getURI ();
2169
- final boolean initialConnectionKeepAlive = future .getKeepAlive ();
2170
- future .setURI (uri );
2171
- final String newUrl = uri .toString ();
2172
-
2173
- log .debug ("Redirecting to {}" , newUrl );
2174
- for (String cookieStr : future .getHttpResponse ().getHeaders (HttpHeaders .Names .SET_COOKIE )) {
2175
- Cookie c = AsyncHttpProviderUtils .parseCookie (cookieStr );
2176
- nBuilder .addOrReplaceCookie (c );
2177
- }
2178
-
2179
- for (String cookieStr : future .getHttpResponse ().getHeaders (HttpHeaders .Names .SET_COOKIE2 )) {
2180
- Cookie c = AsyncHttpProviderUtils .parseCookie (cookieStr );
2181
- nBuilder .addOrReplaceCookie (c );
2182
- }
2183
-
2184
- AsyncCallable ac = new AsyncCallable (future ) {
2185
- public Object call () throws Exception {
2186
- if (initialConnectionKeepAlive && ctx .getChannel ().isReadable () &&
2187
- connectionsPool .offer (AsyncHttpProviderUtils .getBaseUrl (initialConnectionUri ), ctx .getChannel ())) {
2188
- return null ;
2189
- }
2190
- finishChannel (ctx );
2191
- return null ;
2192
- }
2193
- };
2194
-
2195
- if (response .isChunked ()) {
2196
- // We must make sure there is no bytes left before executing the next request.
2197
- ctx .setAttachment (ac );
2198
- } else {
2199
- ac .call ();
2200
- }
2201
- nextRequest (nBuilder .setUrl (newUrl ).build (), future );
2202
- return ;
2203
- }
2204
- } else {
2205
- throw new MaxRedirectException ("Maximum redirect reached: " + config .getMaxRedirects ());
2206
- }
2207
- }
2223
+ if (redirect (request , future , response , ctx )) return ;
2208
2224
2209
2225
if (!future .getAndSetStatusReceived (true ) && updateStatusAndInterrupt (handler , status )) {
2210
2226
finishUpdate (future , ctx , response .isChunked ());
@@ -2297,7 +2313,7 @@ public void handle(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
2297
2313
}
2298
2314
} catch (FilterException efe ) {
2299
2315
abort (future , efe );
2300
- } // @Override
2316
+ }
2301
2317
2302
2318
}
2303
2319
@@ -2310,6 +2326,9 @@ public void handle(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
2310
2326
return ;
2311
2327
}
2312
2328
2329
+ future .setHttpResponse (response );
2330
+ if (redirect (request , future , response , ctx )) return ;
2331
+
2313
2332
final org .jboss .netty .handler .codec .http .HttpResponseStatus status =
2314
2333
new org .jboss .netty .handler .codec .http .HttpResponseStatus (101 , "Web Socket Protocol Handshake" );
2315
2334
0 commit comments