Pavlin Shterev created HTTPCLIENT-2412:
------------------------------------------

             Summary: Resolving future returned from HttpAsyncClient.execute() 
blocks forever when having connection issues with the SOCKS proxy
                 Key: HTTPCLIENT-2412
                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2412
             Project: HttpComponents HttpClient
          Issue Type: Bug
          Components: HttpClient (async)
    Affects Versions: 5.5.2
            Reporter: Pavlin Shterev


We're configuring a 
org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient with a socks 
proxy and all possible timeouts. When there are issues with the socks proxy 
(different cases - no response from the proxy or a TCP reset) resolving the 
future returned by the execute() method call can block forever every 2nd failed 
method call (clarification later).

I have a test that simulates issues with the socks proxy and can simulate no 
response or TCP reset. So if I configure to have TCP reset from the socks proxy 
and call httpClient.execute() - this fails with socket exception - which is 
expected. But if I call it again then the future is never resolved and the 
calling thread is blocked forever. And just for context if after a failed 
execute() I have a successful one, then the next failed one fails expectedly. 
The issue reproduces only when there are 2 consecutive execute() calls while 
having issues with the socks proxy (I'm simulating different issues with the 
socks proxy and in all cases we have the same problem). 

 

This is how we create the client:

final SSLContext sslContext = SSLContexts.custom()
                                    .loadTrustMaterial(null, 
TrustAllStrategy.INSTANCE)
                                    .build();

TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
                                    .setSslContext(sslContext)
                                    
.setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                                    .buildAsync();

Proxy proxy = // get socks proxy address from somewhere
IOReactorConfig ioReactorConfigBuilder = IOReactorConfig.custom()
                                     .setSocksProxyAddress(proxy.address())
                                     .setSoTimeout(Timeout.ofSeconds(10))
                                     .build();

final PoolingAsyncClientConnectionManager cmAsync = 
PoolingAsyncClientConnectionManagerBuilder.create()
                                    .setTlsStrategy(tlsStrategy)
                                    
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
                                    .setConnPoolPolicy(PoolReusePolicy.LIFO)
                                    .setDefaultConnectionConfig(
                                            ConnectionConfig.custom()
                                                    
.setConnectTimeout(Timeout.ofSeconds(5))
                                                    
.setSocketTimeout(Timeout.ofSeconds(5))
                                                    
.setTimeToLive(TimeValue.ofSeconds(10))
                                                    .build())
                                    .build();

                            HttpAsyncClientBuilder builder = 
HttpAsyncClientBuilder.create();
                            builder.setConnectionManager(cmAsync)
                                    .setIOReactorConfig(ioReactorConfigBuilder)
                                    
.setDefaultRequestConfig(RequestConfig.custom()
                                            
.setConnectTimeout(Timeout.ofSeconds(5))
                                            
.setResponseTimeout(Timeout.ofSeconds(5))
                                            
.setConnectionRequestTimeout(Timeout.ofSeconds(5))
                                            .build());
                            http5Client = builder.build();
                            http5Client.start();

Making the request:

 

String url = String.format("https://%s:%d/";, host, port);
SimpleHttpRequest request = SimpleHttpRequest.create(Method.GET, new URI(url));

Future<SimpleHttpResponse> future = http5Client.execute(request, null);
final SimpleHttpResponse response = future.get();  <<<<< THIS POTENTIALLY 
BLOCKS FOREVER

 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to