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]