Ошибка Jetty 9.3 SSL-ALPN-HTTP2 ERR_EMPTY_RESPONSE только с HTTPS

Я обновил сервер Jetty 9.2 только для HTTP/1.1 + SSL (встроенный) до Jetty 9.3.0 (v20150612) HTTP/HTTPS 2.0 (SLL(TLS)-ALPN-HTTP/2). Я использую JRE 8 (Oracle 1.8.0 Build 45 - b15) и Eclipse.

* ПРОБЛЕМА, РЕШЕННАЯ ОТВЕТОМ JOAKIM: решение см. В конце статьи *

До обновления HTTP и HTTPS работали нормально, и все же работали, просто перестраивая файлы Jar Jetty 9.3. Затем я обновил код (изучая примеры, которые мне удалось найти), чтобы включить SSL(TLS)-ALPN-HTTP/2-HTTP/1.1. Основной пример, который я использовал, находится в этой ссылке с кодом

Браузер Google Chrome (версия 43.0.2357.130) отлично работает с запросом http, например http:// 10.32.1.110:8080/, и отображается веб-страница. Но если я открою вторую вкладку и попробую https:// 10.32.1.110:8443/, я получу ошибку ERR_EMPTY_RESPONSE. Однако я могу подключиться к webtide.com и получить сеанс https. Помехи брандмауэра в моей системе были исключены. 10.32.??? соединения не передают это также для рабочего HTTP и для терпящего неудачу HTTPS.

Эта ошибка НЕ ​​блокирует сервер Jetty (сервер не генерирует или не регистрирует ошибку), и я могу вернуться к первой вкладке браузера и продолжить запрашивать веб-страницу, и я вижу ее обновленной (у меня есть отметка времени и счетчик в нем) каждый раз.

В случае HTTPS мой метод handle() не вызывается Jetty (у меня есть строка журнала для мониторинга этого), и я вижу, что только HTTP-запросы приходят в метод handle(). Http-запросы, которые приходят в мой handle(), имеют тип HTTP / 1.1 в соответствии с объектом запроса Jetty. Согласно моим исследованиям, это нормально, потому что Google Chrome НЕ будет выполнять HTTP / 2 без SSL/ALPN.

Я думал о проблемах с SSL и ALPN как о причине, что HTTPS-запросы приводят к ERR_EMPTY_RESPONSE. Файл alpn-api-1.1.2.v20150522.jar добавлен в мои аргументы виртуальной машины Eclipse (эквивалент пути загрузки JVM) как "-Xbootclasspath/p:D:\Users\TWO\DATA\Eclipse\alpn-api-1.1.2.v20150522\alpn-api-1.1.2.v20150522.jar"С тех пор Jetty не жалуется на то, что ALPN не находится в пути загрузки класса JVM (выдавая ошибку, как это было раньше). Из журнала Jetty ниже SLL и HTTP / 2 также запускаются правильно.

Jetty Server запускается нормально с этими журналами:

2015-06-24 15:53:29.292:INFO:oejs.Server:main: jetty-9.3.0.v20150612
2015-06-24 15:53:29.323:INFO:oejs.ServerConnector:main: Started ServerConnector@123772c4{HTTP/1.1,[http/1.1, h2c, h2c-17, h2c-16, h2c-15, h2c-14]}{0.0.0.0:8080}
2015-06-24 15:53:29.338:INFO:oejus.SslContextFactory:main: x509={jetty.eclipse.org=jetty} wild={} alias=null for SslContextFactory@6f75e721(file:///D:/Users/[removed]/keystores/keystore,file:///D:/Users/[removed]/keystores/keystore)
2015-06-24 15:53:29.495:INFO:oejs.ServerConnector:main: Started ServerConnector@13deb50e{SSL,[ssl, alpn, h2, h2-17, h2-16, h2-15, h2-14, http/1.1]}{0.0.0.0:8443}
2015-06-24 15:53:29.495:INFO:oejs.Server:main: Started @321ms

Вот соответствующий код Java-сервера:

... standard Jetty imports plus
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;


QueuedThreadPool oTP = new QueuedThreadPool(20);
this.oServer = new Server(oTP);
this.oServer.setHandler((Handler) this);

HttpConfiguration httpcfg = new HttpConfiguration();
httpcfg.setSecureScheme("https");
httpcfg.setSecurePort(8443);

HttpConnectionFactory httpF=new HttpConnectionFactory(httpcfg);
HTTP2CServerConnectionFactory http2F=new HTTP2CServerConnectionFactory(httpcfg);

ServerConnector http=new ServerConnector(this.oServer,httpF,http2F);
http.setPort(8080);
this.oServer.addConnector(http);

SslContextFactory sslCF=new SslContextFactory();
sslCF.setKeyStorePath(MetaWebServerConfig.getWebServerKeystore()+"keystore"); 
sslCF.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslCF.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
sslCF.setTrustStorePath(MetaWebServerConfig.getWebServerKeystore()+"keystore"); 
sslCF.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");

sslCF.setExcludeCipherSuites(
              "SSL_RSA_WITH_DES_CBC_SHA",
              "SSL_DHE_RSA_WITH_DES_CBC_SHA",
              "SSL_DHE_DSS_WITH_DES_CBC_SHA",
              "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
              "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
              "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
              "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");

sslCF.setCipherComparator(new HTTP2Cipher.CipherComparator());

HttpConfiguration httpscfg = new HttpConfiguration(httpcfg);
httpscfg.addCustomizer(new SecureRequestCustomizer());

HTTP2ServerConnectionFactory h2F=new HTTP2ServerConnectionFactory(httpscfg);

NegotiatingServerConnectionFactory.checkProtocolNegotiationAvailable();
ALPNServerConnectionFactory alpnF=new ALPNServerConnectionFactory();
alpnF.setDefaultProtocol(http.getDefaultProtocol());

SslConnectionFactory sslF=new SslConnectionFactory(sslCF,alpnF.getProtocol());
HttpConnectionFactory https2F=new HttpConnectionFactory(httpscfg);

ServerConnector http2=new ServerConnector(this.oServer,sslF,alpnF,h2F,https2F);
http2.setPort(8443);
this.oServer.addConnector(http2);

ALPN.debug=false;
this.oServer.start();

По запросу gregw я попробовал пример кода, который находится по ссылке вверху. Я только изменил путь к хранилищу ключей для SslContextFactory. Я всегда использую один и тот же файл хранилища ключей, потому что я знаю, что он в порядке (см. Начало статьи - мой старый HTTP/1.1+SLL работал и использовал то же хранилище ключей.

2015-06-25 14:07:14.972:INFO:oejs.Server:main: jetty-9.3.0.v20150612
2015-06-25 14:07:15.019:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@6f75e721{/,file:///D:/Users/[path]/docroot,AVAILABLE}
2015-06-25 14:07:15.082:INFO:oejs.ServerConnector:main: Started ServerConnector@1888ff2c{HTTP/1.1,[http/1.1, h2c, h2c-17, h2c-16, h2c-15, h2c-14]}{0.0.0.0:8080}
2015-06-25 14:07:15.097:INFO:oejus.SslContextFactory:main: x509={jetty.eclipse.org=jetty} wild={} alias=null for SslContextFactory@4b952a2d(file:///D:/Users/[path]/keystores/keystore,null)
2015-06-25 14:07:15.269:INFO:oejs.ServerConnector:main: Started ServerConnector@5594a1b5{SSL,[ssl, alpn, h2, h2-17, h2-16, h2-15, h2-14, http/1.1]}{0.0.0.0:8443}
2015-06-25 14:07:15.269:INFO:oejs.Server:main: Started @587ms

Доступ по http работает, но по https нет, и браузер снова показывает ERR_EMPTY_RESPONSE.

Пробовал с помощью IExplorer 11. Те ​​же результаты. Работает для http, а не для https (msg = эта страница не может быть отображена), не путать с 404 (эта страница не может быть найдена). IE, в отличие от Chrome, предупреждал "Cookie", когда код Грега использовался с http, но не с https.

Есть ли кто-то, кто может иметь представление о том, как решить вышеуказанную проблему. ТИА

* РЕШЕНИЕ *

По предложению Joakim я добавил alpn-boot-8.1.3.v20150130.jar вместо alpn-api-1.1.2.v20150522.jar в путь к загрузочному классу. Тесты в следующих комбинациях работали отлично:

  • HTTP / 1.1 (HTTP) - сделано с помощью Google Chrome
  • HTTP / 1.1 (HTTP) - вторая попытка с IE

  • HTTP / 2.0 + SSL (HTTPS) - сделано с помощью Google Chrome

  • HTTP / 1_1 + SLL (HTTPS) - сделано с IE

  • HTTP/2_0 (HTTP) - не проверялось из-за отсутствия быстрого агента пользователя, выполняющего это.

Это единственные будущие комбинации, которые меня интересуют, хотя я уверен, что HTTP/2_0 с SSL также будет работать.

Эта ссылка на документацию Jetty показывает таблицу между версией JRE и версиями файла JAR ALPN, которую следует использовать в случае, если у одной такой же проблемы с другой JRE.

Большое спасибо всем, кто пытался помочь решить эту проблему.

1 ответ

Решение

Для Oracle/OpenJDK Java JRE/JDK вы используете alpn-boot.jar, а не alpn-api.jar ...

  • Для Java 1.8.0_25 вы используете alpn-boot-8.1.2.v20141202.jar
  • Для Java 1.8.0_45 вы используете alpn-boot-8.1.3.v20150130.jar

См. Документацию ALPN / Versions для таблиц версий от Java до alpn-boot.

Это жизненно важно, так как это изменяет уровень SSL/TLS самого Java, чтобы добавить поддержку протокола ALPN, необходимого для работы HTTP/2.

Это требование -Xbootclasspath является обязательным до тех пор, пока в будущем Java не будет поставляться со встроенным ALPN (что запланировано для Java 9).

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