Hi all I need to create a https client able to connect to HTTP2 enabled web sites.
I tried to access a known HTTP2 web site (https://korben.info <https://korben.info/>) as a test using one of the HTTP2 example provided in https://hc.apache.org/httpcomponents-client-5.0.x/examples-async.html <https://hc.apache.org/httpcomponents-client-5.0.x/examples-async.html> The example is working when negociating protocols because the website is also accessible using HTTP 1.1, but when I try to force the use of HTTP2 via the method setVersionPolicy (parameter HttpVersionPolicy.FORCE_HTTP_2) of the HttpAsyncClientBuilder class, I finally have the following problem : Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.hc.core5.http2.H2ConnectionException: Frame size exceeds maximum at org.apache.hc.core5.concurrent.BasicFuture.getResult(BasicFuture.java:71) at org.apache.hc.core5.concurrent.BasicFuture.get(BasicFuture.java:84) at bcc.httpTestClient.hc.testHTTP2Korben.main(testHTTP2Korben.java:110) Caused by: org.apache.hc.core5.http2.H2ConnectionException: Frame size exceeds maximum at org.apache.hc.core5.http2.impl.nio.FrameInputBuffer.read(FrameInputBuffer.java:101) at org.apache.hc.core5.http2.impl.nio.AbstractHttp2StreamMultiplexer.onInput(AbstractHttp2StreamMultiplexer.java:415) at org.apache.hc.core5.http2.impl.nio.AbstractHttp2IOEventHandler.inputReady(AbstractHttp2IOEventHandler.java:63) at org.apache.hc.core5.http2.impl.nio.ClientHttp2IOEventHandler.inputReady(ClientHttp2IOEventHandler.java:38) at org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:117) at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:50) at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:173) at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:123) at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:80) at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44) at java.lang.Thread.run(Thread.java:745) Any idea about a solution ? Regards RemyA PS: source code package bcc.httpTestClient.hc; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.Future; import javax.net.ssl.SSLContext; 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.SimpleRequestProducer; import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer; 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.H2TlsStrategy; import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.nio.ssl.TlsStrategy; import org.apache.hc.core5.http2.HttpVersionPolicy; import org.apache.hc.core5.io.ShutdownType; import org.apache.hc.core5.reactor.ssl.TlsDetails; import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.TrustStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class testHTTP2Korben { final static Logger logger = LoggerFactory.getLogger(testHTTP2Korben.class); public final static void main(final String[] args) throws Exception { // Trust standard CA and those trusted by our custom strategy final SSLContext sslcontext = SSLContexts.custom() .loadTrustMaterial(new TrustStrategy() { @Override public boolean isTrusted( final X509Certificate[] chain, final String authType) throws CertificateException { final X509Certificate cert = chain[0]; return true; } }) .build(); final TlsStrategy tlsStrategy = new H2TlsStrategy( sslcontext, H2TlsStrategy.getDefaultHostnameVerifier()) { // IMPORTANT uncomment the following method when running Java 9 or older // in order to avoid the illegal reflective access operation warning @Override protected TlsDetails createTlsDetails(final SSLEngine sslEngine) { return new TlsDetails(sslEngine.getSession(), sslEngine.getSession().getProtocol()); } }; final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create() .setTlsStrategy(tlsStrategy) .build(); try (CloseableHttpAsyncClient client = HttpAsyncClients.custom() .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2) //.setVersionPolicy(HttpVersionPolicy.NEGOTIATE) .setConnectionManager(cm) // .setProxy(new HttpHost("localhost", 10050)) .build()) { client.start(); final HttpHost target = new HttpHost("korben.info", 443, "https"); final String requestUri = "/"; final HttpClientContext clientContext = HttpClientContext.create(); final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri); request.setHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:58.0) Gecko/20100101 Firefox/58.0"); request.setHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setHeader(HttpHeaders.ACCEPT_LANGUAGE, "fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3"); 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(requestUri + "->" + response.getCode()); System.out.println(response.getBody()); final SSLSession sslSession = clientContext.getSSLSession(); if (sslSession != null) { System.out.println("SSL protocol " + sslSession.getProtocol()); System.out.println("SSL cipher suite " + sslSession.getCipherSuite()); } } @Override public void failed(final Exception ex) { System.out.println(requestUri + "->" + ex); } @Override public void cancelled() { System.out.println(requestUri + " cancelled"); } }); future.get(); System.out.println("Shutting down"); client.shutdown(ShutdownType.GRACEFUL); } } }
