@@ -140,10 +140,12 @@ public class NettyAsyncHttpProvider extends SimpleChannelUpstreamHandler impleme
140
140
private final static String HTTPS = "https" ;
141
141
private final static String HTTP = "http" ;
142
142
private static final String WEBSOCKET = "ws" ;
143
+ private static final String WEBSOCKET_SSL = "wss" ;
143
144
private final static Logger log = LoggerFactory .getLogger (NettyAsyncHttpProvider .class );
144
145
private final ClientBootstrap plainBootstrap ;
145
146
private final ClientBootstrap secureBootstrap ;
146
147
private final ClientBootstrap webSocketBootstrap ;
148
+ private final ClientBootstrap secureWebSocketBootstrap ;
147
149
private final static int MAX_BUFFERED_BYTES = 8192 ;
148
150
private final AsyncHttpClientConfig config ;
149
151
private final AtomicBoolean isClose = new AtomicBoolean (false );
@@ -198,6 +200,7 @@ public NettyAsyncHttpProvider(AsyncHttpClientConfig config) {
198
200
plainBootstrap = new ClientBootstrap (socketChannelFactory );
199
201
secureBootstrap = new ClientBootstrap (socketChannelFactory );
200
202
webSocketBootstrap = new ClientBootstrap (socketChannelFactory );
203
+ secureWebSocketBootstrap = new ClientBootstrap (socketChannelFactory );
201
204
configureNetty ();
202
205
203
206
this .config = config ;
@@ -305,9 +308,30 @@ public ChannelPipeline getPipeline() throws Exception {
305
308
}
306
309
});
307
310
311
+ secureWebSocketBootstrap .setPipelineFactory (new ChannelPipelineFactory () {
312
+
313
+ /* @Override */
314
+ public ChannelPipeline getPipeline () throws Exception {
315
+ ChannelPipeline pipeline = pipeline ();
316
+
317
+ try {
318
+ pipeline .addLast (SSL_HANDLER , new SslHandler (createSSLEngine ()));
319
+ } catch (Throwable ex ) {
320
+ abort (cl .future (), ex );
321
+ }
322
+
323
+ pipeline .addLast ("ws-decoder" , new HttpResponseDecoder ());
324
+ pipeline .addLast ("ws-encoder" , new HttpRequestEncoder ());
325
+ pipeline .addLast ("httpProcessor" , NettyAsyncHttpProvider .this );
326
+
327
+ return pipeline ;
328
+ }
329
+ });
330
+
308
331
if (asyncHttpProviderConfig != null ) {
309
332
for (Entry <String , Object > entry : asyncHttpProviderConfig .propertiesSet ()) {
310
333
secureBootstrap .setOption (entry .getKey (), entry .getValue ());
334
+ secureWebSocketBootstrap .setOption (entry .getKey (), entry .getValue ());
311
335
}
312
336
}
313
337
}
@@ -344,7 +368,7 @@ private Channel verifyChannelPipeline(Channel channel, String scheme) throws IOE
344
368
channel .getPipeline ().remove (SSL_HANDLER );
345
369
} else if (channel .getPipeline ().get (HTTP_HANDLER ) != null && HTTP .equalsIgnoreCase (scheme )) {
346
370
return channel ;
347
- } else if (channel .getPipeline ().get (SSL_HANDLER ) == null && HTTPS . equalsIgnoreCase (scheme )) {
371
+ } else if (channel .getPipeline ().get (SSL_HANDLER ) == null && isSecure (scheme )) {
348
372
channel .getPipeline ().addFirst (SSL_HANDLER , new SslHandler (createSSLEngine ()));
349
373
}
350
374
return channel ;
@@ -508,7 +532,7 @@ protected final static HttpRequest buildRequest(AsyncHttpClientConfig config, Re
508
532
boolean allowConnect , ChannelBuffer buffer ) throws IOException {
509
533
510
534
String method = request .getMethod ();
511
- if (allowConnect && (isProxyServer (config , request ) && HTTPS . equalsIgnoreCase (uri . getScheme () ))) {
535
+ if (allowConnect && (isProxyServer (config , request ) && isSecure (uri ))) {
512
536
method = HttpMethod .CONNECT .toString ();
513
537
}
514
538
return construct (config , request , new HttpMethod (method ), uri , buffer );
@@ -542,7 +566,7 @@ private static HttpRequest construct(AsyncHttpClientConfig config,
542
566
}
543
567
nettyRequest = new DefaultHttpRequest (HttpVersion .HTTP_1_1 , m , path .toString ());
544
568
}
545
- boolean webSocket = uri . getScheme (). equalsIgnoreCase ( WEBSOCKET );
569
+ boolean webSocket = isWebSocket ( uri );
546
570
if (webSocket ) {
547
571
nettyRequest .addHeader (HttpHeaders .Names .UPGRADE , HttpHeaders .Values .WEBSOCKET );
548
572
nettyRequest .addHeader (HttpHeaders .Names .CONNECTION , HttpHeaders .Values .UPGRADE );
@@ -762,7 +786,8 @@ private static HttpRequest construct(AsyncHttpClientConfig config,
762
786
/**
763
787
* TODO: AHC-78: SSL + zero copy isn't supported by the MultiPart class and pretty complex to implements.
764
788
*/
765
- if (uri .toString ().startsWith (HTTPS )) {
789
+
790
+ if (isSecure (uri )) {
766
791
ChannelBuffer b = ChannelBuffers .dynamicBuffer (lenght );
767
792
mre .writeRequest (new ChannelBufferOutputStream (b ));
768
793
nettyRequest .setContent (b );
@@ -810,6 +835,7 @@ public void close() {
810
835
plainBootstrap .releaseExternalResources ();
811
836
secureBootstrap .releaseExternalResources ();
812
837
webSocketBootstrap .releaseExternalResources ();
838
+ secureWebSocketBootstrap .releaseExternalResources ();
813
839
} catch (Throwable t ) {
814
840
log .warn ("Unexpected error on close" , t );
815
841
}
@@ -872,7 +898,7 @@ private <T> ListenableFuture<T> doConnect(final Request request, final AsyncHand
872
898
bufferedBytes = f .getNettyRequest ().getContent ();
873
899
}
874
900
875
- boolean useSSl = uri . getScheme (). compareToIgnoreCase ( HTTPS ) == 0 && proxyServer == null ;
901
+ boolean useSSl = isSecure ( uri ) && proxyServer == null ;
876
902
if (channel != null && channel .isOpen () && channel .isConnected ()) {
877
903
HttpRequest nettyRequest = buildRequest (config , request , uri , f == null ? false : f .isConnectAllowed (), bufferedBytes );
878
904
@@ -946,7 +972,7 @@ private <T> ListenableFuture<T> doConnect(final Request request, final AsyncHand
946
972
}
947
973
948
974
ChannelFuture channelFuture ;
949
- ClientBootstrap bootstrap = request .getUrl ().startsWith (WEBSOCKET ) ? webSocketBootstrap : (useSSl ? secureBootstrap : plainBootstrap );
975
+ ClientBootstrap bootstrap = request .getUrl ().startsWith (WEBSOCKET ) ? ( useSSl ? secureWebSocketBootstrap : webSocketBootstrap ) : (useSSl ? secureBootstrap : plainBootstrap );
950
976
bootstrap .setOption ("connectTimeoutMillis" , config .getConnectionTimeoutInMs ());
951
977
952
978
// Do no enable this with win.
@@ -1294,7 +1320,7 @@ private void upgradeProtocol(ChannelPipeline p, String scheme) throws IOExceptio
1294
1320
p .remove (HTTP_HANDLER );
1295
1321
}
1296
1322
1297
- if (scheme . startsWith ( HTTPS )) {
1323
+ if (isSecure ( scheme )) {
1298
1324
if (p .get (SSL_HANDLER ) == null ) {
1299
1325
p .addFirst (HTTP_HANDLER , new HttpClientCodec ());
1300
1326
p .addFirst (SSL_HANDLER , new SslHandler (createSSLEngine ()));
@@ -2372,5 +2398,20 @@ public void onClose(ChannelHandlerContext ctx, ChannelStateEvent e) {
2372
2398
}
2373
2399
}
2374
2400
}
2401
+
2402
+ private static boolean isWebSocket (URI uri )
2403
+ {
2404
+ return WEBSOCKET .equalsIgnoreCase (uri .getScheme ()) || WEBSOCKET_SSL .equalsIgnoreCase (uri .getScheme ());
2405
+ }
2406
+
2407
+ private static boolean isSecure (String scheme )
2408
+ {
2409
+ return HTTPS .equalsIgnoreCase (scheme ) || WEBSOCKET_SSL .equalsIgnoreCase (scheme );
2410
+ }
2411
+
2412
+ private static boolean isSecure (URI uri )
2413
+ {
2414
+ return isSecure (uri .getScheme ());
2415
+ }
2375
2416
}
2376
2417
0 commit comments