我已将 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。我使用的主要示例 在此链接中,带有代码
Google Chrome(版本 43.0.2357.130 m)浏览器可以很好地处理 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 情况下,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 Arguments(相当于 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@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 混淆(无法找到此页面)。与 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) - 使用谷歌浏览器完成
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 文档链接显示了 JRE 版本和 ALPN JAR 文件版本之间的表格,以防一个人与另一个 JRE 有相同的问题。
非常感谢所有试图帮助解决这个问题的人。