1
1
package org .asynchttpclient .providers .netty4 ;
2
2
3
- import static io .netty .handler .codec .http .HttpResponseStatus .CONTINUE ;
4
- import static io .netty .handler .codec .http .HttpResponseStatus .FOUND ;
5
- import static io .netty .handler .codec .http .HttpResponseStatus .MOVED_PERMANENTLY ;
6
- import static io .netty .handler .codec .http .HttpResponseStatus .OK ;
7
- import static io .netty .handler .codec .http .HttpResponseStatus .PROXY_AUTHENTICATION_REQUIRED ;
8
- import static io .netty .handler .codec .http .HttpResponseStatus .SEE_OTHER ;
9
- import static io .netty .handler .codec .http .HttpResponseStatus .TEMPORARY_REDIRECT ;
10
- import static io .netty .handler .codec .http .HttpResponseStatus .UNAUTHORIZED ;
11
- import static org .asynchttpclient .providers .netty4 .util .HttpUtil .HTTP ;
12
- import static org .asynchttpclient .providers .netty4 .util .HttpUtil .WEBSOCKET ;
13
- import static org .asynchttpclient .providers .netty4 .util .HttpUtil .isNTLM ;
3
+ import static io .netty .handler .codec .http .HttpResponseStatus .*;
4
+ import static org .asynchttpclient .providers .netty4 .util .HttpUtil .*;
14
5
import io .netty .buffer .Unpooled ;
15
6
import io .netty .channel .Channel ;
7
+ import io .netty .channel .ChannelHandler .Sharable ;
16
8
import io .netty .channel .ChannelHandlerContext ;
17
9
import io .netty .channel .ChannelInboundHandlerAdapter ;
18
- import io .netty .channel .ChannelHandler .Sharable ;
19
10
import io .netty .handler .codec .PrematureChannelClosureException ;
20
11
import io .netty .handler .codec .http .DefaultHttpContent ;
21
12
import io .netty .handler .codec .http .HttpClientCodec ;
@@ -73,15 +64,15 @@ public class NettyChannelHandler extends ChannelInboundHandlerAdapter {
73
64
private final AsyncHttpClientConfig config ;
74
65
private final NettyRequestSender requestSender ;
75
66
private final Channels channels ;
76
- private final AtomicBoolean isClose ;
67
+ private final AtomicBoolean closed ;
77
68
private final Protocol httpProtocol = new HttpProtocol ();
78
69
private final Protocol webSocketProtocol = new WebSocketProtocol ();
79
70
80
71
public NettyChannelHandler (AsyncHttpClientConfig config , NettyRequestSender requestSender , Channels channels , AtomicBoolean isClose ) {
81
72
this .config = config ;
82
73
this .requestSender = requestSender ;
83
74
this .channels = channels ;
84
- this .isClose = isClose ;
75
+ this .closed = isClose ;
85
76
}
86
77
87
78
@ Override
@@ -117,7 +108,7 @@ public void channelRead(final ChannelHandlerContext ctx, Object e) throws Except
117
108
118
109
public void channelInactive (ChannelHandlerContext ctx ) throws Exception {
119
110
120
- if (isClose .get ()) {
111
+ if (closed .get ()) {
121
112
return ;
122
113
}
123
114
@@ -137,7 +128,7 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
137
128
callback .call ();
138
129
139
130
} else if (attachment instanceof NettyResponseFuture <?>) {
140
- NettyResponseFuture future = ( NettyResponseFuture ) attachment ;
131
+ NettyResponseFuture <?> future = NettyResponseFuture . class . cast ( attachment ) ;
141
132
future .touch ();
142
133
143
134
if (!config .getIOExceptionFilters ().isEmpty () && applyIoExceptionFiltersAndReplayRequest (ctx , future , new IOException ("Channel Closed" ))) {
@@ -219,8 +210,8 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Excep
219
210
}
220
211
}
221
212
222
- Protocol p = ( ctx .pipeline ().get (HttpClientCodec .class ) != null ? httpProtocol : webSocketProtocol ) ;
223
- p .onError (ctx , e );
213
+ Protocol protocol = ctx .pipeline ().get (HttpClientCodec .class ) != null ? httpProtocol : webSocketProtocol ;
214
+ protocol .onError (ctx , e );
224
215
225
216
channels .closeChannel (ctx );
226
217
// FIXME not really sure
@@ -253,9 +244,11 @@ private boolean applyIoExceptionFiltersAndReplayRequest(ChannelHandlerContext ct
253
244
254
245
private boolean redirect (Request request , NettyResponseFuture <?> future , HttpResponse response , final ChannelHandlerContext ctx ) throws Exception {
255
246
256
- int statusCode = response .getStatus ().code ();
247
+ io .netty .handler .codec .http .HttpResponseStatus status = response .getStatus ();
248
+ // int statusCode = response.getStatus().code();
257
249
boolean redirectEnabled = request .isRedirectOverrideSet () ? request .isRedirectEnabled () : config .isRedirectEnabled ();
258
- if (redirectEnabled && (statusCode == MOVED_PERMANENTLY .code () || statusCode == FOUND .code () || statusCode == SEE_OTHER .code () || statusCode == TEMPORARY_REDIRECT .code ())) {
250
+ boolean isRedirectStatus = status == MOVED_PERMANENTLY || status == FOUND || status == SEE_OTHER || status == TEMPORARY_REDIRECT ;
251
+ if (redirectEnabled && isRedirectStatus ) {
259
252
260
253
if (future .incrementAndGetCurrentRedirectCount () < config .getMaxRedirects ()) {
261
254
// We must allow 401 handling again.
@@ -270,13 +263,12 @@ private boolean redirect(Request request, NettyResponseFuture<?> future, HttpRes
270
263
nBuilder .setQueryParameters (null );
271
264
}
272
265
273
- // FIXME what about 307?
274
- if (!( statusCode < FOUND . code () || statusCode > SEE_OTHER . code ()) && !(statusCode == FOUND . code () && config .isStrict302Handling ())) {
266
+ // FIXME why not do that for 301 and 307 too ?
267
+ if (( status == FOUND || status == SEE_OTHER ) && !(status == FOUND && config .isStrict302Handling ())) {
275
268
nBuilder .setMethod (HttpMethod .GET .name ());
276
269
}
277
270
278
- // in case of a redirect from HTTP to HTTPS, those values
279
- // might be different
271
+ // in case of a redirect from HTTP to HTTPS, future attributes might change
280
272
final boolean initialConnectionKeepAlive = future .isKeepAlive ();
281
273
final String initialPoolKey = channels .getPoolKey (future );
282
274
@@ -285,8 +277,8 @@ private boolean redirect(Request request, NettyResponseFuture<?> future, HttpRes
285
277
if (request .getUrl ().startsWith (WEBSOCKET )) {
286
278
newUrl = newUrl .replace (HTTP , WEBSOCKET );
287
279
}
288
-
289
280
LOGGER .debug ("Redirecting to {}" , newUrl );
281
+
290
282
for (String cookieStr : future .getHttpResponse ().headers ().getAll (HttpHeaders .Names .SET_COOKIE )) {
291
283
for (Cookie c : CookieDecoder .decode (cookieStr )) {
292
284
nBuilder .addOrReplaceCookie (c );
@@ -310,8 +302,10 @@ public void call() throws Exception {
310
302
if (HttpHeaders .isTransferEncodingChunked (response )) {
311
303
// We must make sure there is no bytes left before
312
304
// executing the next request.
305
+ // FIXME investigate this
313
306
Channels .setDefaultAttribute (ctx , callback );
314
307
} else {
308
+ // FIXME don't understand: this offers the connection to the pool, or even closes it, while the request has not been sent, right?
315
309
callback .call ();
316
310
}
317
311
@@ -590,6 +584,7 @@ public void call() throws Exception {
590
584
} else if (statusCode == CONTINUE .code ()) {
591
585
future .getAndSetWriteHeaders (false );
592
586
future .getAndSetWriteBody (true );
587
+ // FIXME is this necessary
593
588
future .setIgnoreNextContents (true );
594
589
requestSender .writeRequest (ctx .channel (), config , future );
595
590
return ;
@@ -623,7 +618,7 @@ public void call() throws Exception {
623
618
return ;
624
619
}
625
620
626
- } else if (statusCode == OK .code () && nettyRequest .getMethod (). equals ( HttpMethod .CONNECT ) ) {
621
+ } else if (statusCode == OK .code () && nettyRequest .getMethod () == HttpMethod .CONNECT ) {
627
622
628
623
LOGGER .debug ("Connected to {}:{}" , proxyServer .getHost (), proxyServer .getPort ());
629
624
@@ -764,9 +759,7 @@ public void handle(ChannelHandlerContext ctx, NettyResponseFuture future, Object
764
759
if (redirect (request , future , response , ctx ))
765
760
return ;
766
761
767
- io .netty .handler .codec .http .HttpResponseStatus status = io .netty .handler .codec .http .HttpResponseStatus .SWITCHING_PROTOCOLS ;
768
-
769
- boolean validStatus = response .getStatus ().equals (status );
762
+ boolean validStatus = response .getStatus () == SWITCHING_PROTOCOLS ;
770
763
boolean validUpgrade = response .headers ().get (HttpHeaders .Names .UPGRADE ) != null ;
771
764
String c = response .headers ().get (HttpHeaders .Names .CONNECTION );
772
765
if (c == null ) {
0 commit comments