@@ -97,6 +97,13 @@ public NettyRequestSender(AsyncHttpClientConfig config, ChannelManager channelMa
97
97
requestFactory = new NettyRequestFactory (config );
98
98
}
99
99
100
+ // needConnect returns true if the request is secure/websocket and a HTTP proxy is set
101
+ private boolean needConnect (final Request request , final ProxyServer proxyServer ) {
102
+ return proxyServer != null
103
+ && proxyServer .getProxyType ().isHttp ()
104
+ && (request .getUri ().isSecured () || request .getUri ().isWebSocket ());
105
+ }
106
+
100
107
public <T > ListenableFuture <T > sendRequest (final Request request , final AsyncHandler <T > asyncHandler , NettyResponseFuture <T > future ) {
101
108
if (isClosed ()) {
102
109
throw new IllegalStateException ("Closed" );
@@ -106,9 +113,7 @@ public <T> ListenableFuture<T> sendRequest(final Request request, final AsyncHan
106
113
ProxyServer proxyServer = getProxyServer (config , request );
107
114
108
115
// WebSockets use connect tunneling to work with proxies
109
- if (proxyServer != null && proxyServer .getProxyType ().isHttp () &&
110
- (request .getUri ().isSecured () || request .getUri ().isWebSocket ()) &&
111
- !isConnectAlreadyDone (request , future )) {
116
+ if (needConnect (request , proxyServer ) && !isConnectAlreadyDone (request , future )) {
112
117
// Proxy with HTTPS or WebSocket: CONNECT for sure
113
118
if (future != null && future .isConnectAllowed ()) {
114
119
// Perform CONNECT
@@ -125,6 +130,8 @@ public <T> ListenableFuture<T> sendRequest(final Request request, final AsyncHan
125
130
126
131
private static boolean isConnectAlreadyDone (Request request , NettyResponseFuture <?> future ) {
127
132
return future != null
133
+ // If the channel can't be reused or closed, a CONNECT is still required
134
+ && future .isReuseChannel () && Channels .isChannelActive (future .channel ())
128
135
&& future .getNettyRequest () != null
129
136
&& future .getNettyRequest ().getHttpRequest ().method () == HttpMethod .CONNECT
130
137
&& !request .getMethod ().equals (CONNECT );
@@ -137,11 +144,19 @@ private static boolean isConnectAlreadyDone(Request request, NettyResponseFuture
137
144
*/
138
145
private <T > ListenableFuture <T > sendRequestWithCertainForceConnect (Request request , AsyncHandler <T > asyncHandler , NettyResponseFuture <T > future ,
139
146
ProxyServer proxyServer , boolean performConnectRequest ) {
140
- NettyResponseFuture <T > newFuture = newNettyRequestAndResponseFuture (request , asyncHandler , future , proxyServer , performConnectRequest );
141
147
Channel channel = getOpenChannel (future , request , proxyServer , asyncHandler );
142
- return Channels .isChannelActive (channel )
143
- ? sendRequestWithOpenChannel (newFuture , asyncHandler , channel )
144
- : sendRequestWithNewChannel (request , proxyServer , newFuture , asyncHandler );
148
+ if (Channels .isChannelActive (channel )) {
149
+ NettyResponseFuture <T > newFuture = newNettyRequestAndResponseFuture (request , asyncHandler , future ,
150
+ proxyServer , performConnectRequest );
151
+ return sendRequestWithOpenChannel (newFuture , asyncHandler , channel );
152
+ } else {
153
+ // A new channel is not expected when performConnectRequest is false. We need to
154
+ // revisit the condition of sending
155
+ // the CONNECT request to the new channel.
156
+ NettyResponseFuture <T > newFuture = newNettyRequestAndResponseFuture (request , asyncHandler , future ,
157
+ proxyServer , needConnect (request , proxyServer ));
158
+ return sendRequestWithNewChannel (request , proxyServer , newFuture , asyncHandler );
159
+ }
145
160
}
146
161
147
162
/**
0 commit comments