Jetty 9.3 SSL-ALPN-HTTP2 错误 ERR_EMPTY_RESPONSE 仅使用 HTTPS
Posted
技术标签:
【中文标题】Jetty 9.3 SSL-ALPN-HTTP2 错误 ERR_EMPTY_RESPONSE 仅使用 HTTPS【英文标题】:Jetty 9.3 SSL-ALPN-HTTP2 error ERR_EMPTY_RESPONSE with HTTPS only 【发布时间】:2015-09-10 22:49:39 【问题描述】:我已将 Jetty 9.2 HTTP/1.1 + SSL only 服务器(嵌入式)升级到 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 工作正常,并且通过简单地使用 Jetty 9.3 Jar 文件重新构建仍然可以正常工作。然后我升级了代码(从我设法找到的示例中学习)以合并 SSL(TLS)-ALPN-HTTP/2-HTTP/1.1。我使用的主要示例是 in this link with code
Google Chrome(版本 43.0.2357.130 m)浏览器可以很好地处理 http://10.32.1.110:8080/ 等 http 请求并显示网页。但是,如果我打开第二个选项卡并尝试 https://10.32.1.110:8443/,我会收到错误 ERR_EMPTY_RESPONSE。但是,我可以连接到 webtide.com 并获得一个 https 会话。已排除防火墙对我的系统的干扰。 10.32.???与失败的 HTTPS 相比,工作 HTTP 的连接没有通过它。
此错误不会阻止 Jetty 服务器(服务器不会抛出或记录错误),我可以返回第一个浏览器选项卡并继续请求网页,我看到它已更新(我有时间- 每次都在里面盖章和计数器。
在 HTTPS 情况下,Jetty 不会调用我的 handle() 方法(我有一个日志行来监控它),我看到只有 HTTP 请求来自 handle() 方法。根据 Jetty 请求对象,到达我的 handle() 的 http 请求属于 HTTP/1.1 类型。根据我的研究,这是正常的,因为 Google Chrome 不会在没有 SSL/ALPN 的情况下执行 HTTP/2。
我一直在思考 SSL 和 ALPN 问题是 HTTPS 请求导致 ERR_EMPTY_RESPONSE 的原因。 alpn-api-1.1.2.v20150522.jar 以“-Xbootclasspath/p:D:\Users\TWO\DATA\Eclipse\alpn-api-1.1.2”的形式添加到我的 Eclipse VM 参数(相当于 JVM 引导类路径)中.v20150522\alpn-api-1.1.2.v20150522.jar" 从那时起,Jetty 不再抱怨 ALPN 不在 JVM 引导类路径上(通过像以前一样抛出错误)。从下面的 Jetty 日志中,SLL 和 HTTP/2 也正确启动。
Jetty 服务器正常启动时会出现以下日志:
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@123772c4HTTP/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@13deb50eSSL,[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@1888ff2cHTTP/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@5594a1b5SSL,[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 混淆(无法找到此页面)。与 Chrome 相比,IE 确实在 greg 的代码与 http 一起使用时给出了“Cookie”警告,但它没有与 https 一起使用。
是否有人可能知道如何解决上述问题。 TIA
* 解决方案 *
按照 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) - 使用谷歌浏览器完成
HTTP/1_1 + SLL (HTTPS) - 用 IE 完成
HTTP/2_0 (HTTP) - 由于缺少快速用户代理,因此未进行测试。
这些是我感兴趣的唯一未来组合,尽管我确信带有 SSL 的 HTTP/2_0 也可以工作。
Jetty Documentation link 显示了 JRE 版本和 ALPN JAR 文件版本之间的表格,以防万一另一个 JRE 出现相同问题。
非常感谢所有试图帮助解决此问题的人。
【问题讨论】:
您的 alpn-boot.jar 和 alpn-api.jar 的版本在很大程度上取决于您正在运行的 java 的特定版本。仅仅说“JRE8”不足以给出答案。必须知道细节才能提供帮助。什么供应商? (oracle?openjdk?icedtea?ibm?等)。建什么?什么版本/更新?还包括你的命令行启动,因为 ALPN 有一个特定的 -Xbootclasspath 要求。 你能把你正在使用的浏览器指向webtide.com,看看它是否适合你(并检查它是否是http2)。该网站正在运行 9.3.1 的已发布版本,因此它应该与您的代码几乎相同。 请注意,您的代码看起来非常正确。我看不出有什么特别不对劲的地方。但是要仔细检查,您可以尝试码头代码库中的类似示例:github.com/eclipse/jetty.project/blob/master/examples/embedded/… 看看是否适合您。 JRE8 是 Oracle JavaSE 1.8 版本 1.8.0_05 (2014) joakim,JRE8 是 Oracle JavaSE 1.8 版本 1.8.0_05 (2014)。通过 Eclipse VM Arguments 的命令行是 -Xbootclasspath/p:D:\Users\TWO\DATA\Eclipse\alpn-api-1.1.2.v20150522\alpn-api-1.1.2.v20150522.jar。由于 Java JRE8 版本对 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 版本的表格。
这非常重要,因为这会修改 Java 本身的 SSL/TLS 层以添加对 HTTP/2 运行所需的 ALPN 协议的支持。
这个 -Xbootclasspath 要求是强制性的,直到将来 Java 附带 ALPN 内置(计划用于 Java 9)
【讨论】:
乔金,谢谢。我会立即开始查看并报告。 joakim,您的解决方案解决了问题。我已经用所有组合测试的结果更新了主要消息,现在它可以完美运行。我会记住你的 cmets 关于 JRE8 构建版本与 ALPN 文件版本的未来。 接受答案,按照预期的方式使用***。 (更新/编辑说答案正确的问题不是它是如何完成的) joakim,我不是一个经常使用 *** 的用户。我会随着我去适应。感谢您为我指明正确的方向并提供有效的解决方案。 我们都必须从某个地方开始,欢迎来到这个网站。小心它可能会上瘾。 :-)以上是关于Jetty 9.3 SSL-ALPN-HTTP2 错误 ERR_EMPTY_RESPONSE 仅使用 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章
Jetty websocket 客户端类 WebSocketClient 线程安全吗?