Andrei Vasilev created HTTPCLIENT-2177:
------------------------------------------
Summary: Unable to use HTTP Proxy with CloseableHttpAsyncClient
Key: HTTPCLIENT-2177
URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2177
Project: HttpComponents HttpClient
Issue Type: Bug
Components: HttpClient (async)
Affects Versions: 5.1, 5.0
Environment: Windows 10.0.19041 Build 19041
Java 11.0.11
Gradle 6.8
Reporter: Andrei Vasilev
When executing a standard GET request with a configured proxy (authenticated or
not) using an instance of CloseableHttpAsyncClient, the request fails with
"IllegalStateException: No tunnel unless connected."
Is making requests via proxies using an AsyncClient not supported? It is not
entirely clear from the current release notes/examples.
Minimal example to reproduce issue, although you will of course need to
configure the proxy accordingly given your environment.
{code:java}
import java.util.concurrent.Future;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import
org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.function.Factory;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
public class AsyncMain {
public static void main(final String[] args) throws Exception {
final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
.useSystemProperties()
.setTlsDetailsFactory(new Factory<SSLEngine, TlsDetails>() {
@Override
public TlsDetails create(final SSLEngine sslEngine) {
return new TlsDetails(sslEngine.getSession(),
sslEngine.getApplicationProtocol());
}
}).build();
final PoolingAsyncClientConnectionManager cm =
PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(tlsStrategy)
.build();
try (final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.setConnectionManager(cm)
.build()) {
client.start();
final HttpClientContext clientContext = HttpClientContext.create();
final HttpHost target = new HttpHost("https", "nghttp2.org");
final HttpHost proxy = new HttpHost("127.0.0.1", 8888);
final RequestConfig config =
RequestConfig.custom().setProxy(proxy).build();
final SimpleHttpRequest request = SimpleRequestBuilder.get()
.setHttpHost(target)
.setRequestConfig(config)
.setPath("/httpbin/")
.build();
System.out.println("Executing request " + request);
final Future<SimpleHttpResponse> future = client.execute(
SimpleRequestProducer.create(request),
SimpleResponseConsumer.create(),
clientContext,
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
System.out.println(request + "->" + new StatusLine(response));
final SSLSession sslSession = clientContext.getSSLSession();
if (sslSession != null) {
System.out.println("SSL protocol " + sslSession.getProtocol());
System.out.println("SSL cipher suite " +
sslSession.getCipherSuite());
}
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
System.out.println(request + "->" + ex);
}
@Override
public void cancelled() {
System.out.println(request + " cancelled");
}
});
future.get();
System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);
}
}
}
{code}
The resulting stack trace :
{code:java}
Exception in thread "main" java.util.concurrent.ExecutionException:
java.lang.IllegalStateException: No tunnel unless connected at
org.apache.hc.core5.concurrent.BasicFuture.getResult(BasicFuture.java:72) at
org.apache.hc.core5.concurrent.BasicFuture.get(BasicFuture.java:85) at
AsyncMain.main(AsyncMain.java:86)Caused by: java.lang.IllegalStateException: No
tunnel unless connected at
org.apache.hc.core5.util.Asserts.check(Asserts.java:38) at
org.apache.hc.client5.http.RouteTracker.tunnelTarget(RouteTracker.java:143) at
org.apache.hc.client5.http.impl.async.AsyncConnectExec$4.completed(AsyncConnectExec.java:270)
at
org.apache.hc.client5.http.impl.async.AsyncConnectExec$5.completed(AsyncConnectExec.java:388)
at
org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec$1.consumeResponse(HttpAsyncMainClientExec.java:206)
at
org.apache.hc.core5.http.impl.nio.ClientHttp1StreamHandler.consumeHeader(ClientHttp1StreamHandler.java:253)
at
org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.consumeHeader(ClientHttp1StreamDuplexer.java:348)
at
org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.consumeHeader(ClientHttp1StreamDuplexer.java:80)Caused
by: java.lang.IllegalStateException: No tunnel unless connected
at
org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onInput(AbstractHttp1StreamDuplexer.java:288)
at
org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.inputReady(AbstractHttp1IOEventHandler.java:64)
at
org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler.inputReady(ClientHttp1IOEventHandler.java:39)
at
org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:131)
at
org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:51)
at
org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:178)
at
org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:127)
at
org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:85)
at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44) at
java.base/java.lang.Thread.run(Thread.java:829)
{code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]