HTTP2 URL успешно загружается в браузере, но не работает в httpclient5

Я пытаюсь создать пример httpclient 5, который загружает URL с помощью asynchttpclient(асинхронное мультиплексирование) с этим примером. Я настроил tomcat 9 для приема протокола http2 с помощью конфигурации conf/server.xml следующим образом

<Connector
       protocol="org.apache.coyote.http11.Http11NioProtocol"
       port="8443" maxThreads="200"
       scheme="https" secure="true" SSLEnabled="true"
       keystoreFile="conf/xxx.keystore" keystorePass="xxx#"
       clientAuth="false" sslProtocol="TLS"><UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/></Connector>

и моя программа выглядит следующим образом,

    final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustAllStrategy()).build();
    final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create().setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE)).build();
    final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoTimeout(Timeout.ofSeconds(5)).build();
    final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig, connectionManager);


    client.start();

    final HttpHost target = new HttpHost("localhost", 8084, "https");
    System.out.println(target.getPort());
    final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
    final AsyncClientEndpoint endpoint = leaseFuture.get(45, TimeUnit.SECONDS);
    try {
        final String[] requestUris = new String[] {"/index.html"};

        final CountDownLatch latch = new CountDownLatch(requestUris.length);
        for (final String requestUri: requestUris) {
            final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);

            endpoint.execute(SimpleRequestProducer.create(request), SimpleResponseConsumer.create(), new FutureCallback<SimpleHttpResponse>() {
                        @Override
                        public void completed(final SimpleHttpResponse response) {
                            latch.countDown();
                            System.out.println(requestUri + "->" + response.getCode());
                            System.out.println(response.getBody());
                        }

                        @Override
                        public void failed(final Exception ex) {
                            latch.countDown();
                            System.out.println(requestUri + "->" + ex);
                            ex.printStackTrace();
                        }

                        @Override
                        public void cancelled() {
                            latch.countDown();
                            System.out.println(requestUri + " cancelled");
                        }

                    });
        }
        latch.await();
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        endpoint.releaseAndReuse();
    }

    client.shutdown(ShutdownType.GRACEFUL);

Конфигурация tomcat работает при загрузке страницы в borwser с протоколом h2, но не работает с httpclient 5 со следующим исключением

/index.html->org.apache.hc.core5.http.ConnectionClosedException: Connection closed
org.apache.hc.core5.http.ConnectionClosedException: Connection closed
    at org.apache.hc.core5.http2.impl.nio.FrameInputBuffer.read(FrameInputBuffer.java:146)
    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:748)

Любая помощь по этому вопросу будет принята с благодарностью

Заранее спасибо

При включении журналов Tomcat, я вижу следующее,

org.apache.coyote.AbstractProtocol $ ConnectionHandler.process Не удалось создать процессор для согласованного протокола [h2c]

Даже эта проблема исправлена, когда я обновляю код клиента до java 9, но возможно ли заставить его работать с java 8.

PS: я знаю, что Java 8 не поддерживает ALPN, но дайте мне знать, если есть какие-либо средства, я могу заставить его работать с Java 8.

2 ответа

Используя concerypt в качестве поставщика по умолчанию и настраивая TLSStrategy, мы можем заставить его работать с jdk1.8, см.

/questions/5813938/conscrypt-s-jdk8-chtobyi-vklyuchit-alpn-dlya-http2/5813954#5813954

Я столкнулся с подобной проблемой и обнаружил, что это связано с использованием протокола запроса в качестве https. Поскольку я уже настраивал стратегию TLS для клиента, изменение протокола на простое "http" решило проблему. Замените строку: final HttpHost target = new HttpHost("localhost", 8084, "https"); по окончанию HttpHost target = new HttpHost("localhost", 8084, "http");

Другие вопросы по тегам