【问题标题】:Jetty ssl factory using http2 doesn't work使用 http2 的 Jetty ssl 工厂不起作用
【发布时间】:2021-01-11 20:59:23
【问题描述】:

我有一个使用 jetty 的简单 Spring Boot 项目。

我在 443 端口上运行并使用 http1.1 就好了

@Bean(name = "containerCustomizer")
public WebServerFactoryCustomizer containerCustomizer()
{
    return (container -> ((JettyServletWebServerFactory) container).addServerCustomizers(server -> {
        // HTTPS
        SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
        sslContextFactory.setKeyStoreResource(Resource.newResource(
                getClass().getClassLoader().getResource("keystore.jks")));
        sslContextFactory.setKeyStorePassword("password");
        sslContextFactory.setProtocol("TLS");
        sslContextFactory.setKeyStoreType("JKS");

        HttpConfiguration https = new HttpConfiguration();
        https.addCustomizer(new SecureRequestCustomizer());
        SslConnectionFactory sslFactory = new SslConnectionFactory(sslContextFactory,
                                                                   HttpVersion.HTTP_1_1.asString());
        ServerConnector sslConnector = new ServerConnector(server, sslFactory, new HttpConnectionFactory(https));
        sslConnector.setPort(443);
        server.setConnectors(new Connector[] {sslConnector});
    }));
}

但是,一旦我通过将 HttpVersion.HTTP_1_1.asString() 替换为 HttpVersion.HTTP_2.asString() 来更改为 HTTP2,就会出现异常

Caused by: java.lang.IllegalStateException: No protocol factory for SSL next protocol: 'HTTP/2.0' in ServerConnector@61e45f87{SSL, (ssl, http/1.1)}{0.0.0.0:443}
    at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:317) ~[jetty-server-9.4.35.v20201120.jar:9.4.35.v20201120]
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81) ~[jetty-server-9.4.35.v20201120.jar:9.4.35.v20201120]
    at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:234) ~[jetty-server-9.4.35.v20201120.jar:9.4.35.v20201120]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73) ~[jetty-util-9.4.35.v20201120.jar:9.4.35.v20201120]
    at org.springframework.boot.web.embedded.jetty.JettyWebServer.start(JettyWebServer.java:174) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
    ... 16 common frames omitted

【问题讨论】:

    标签: java spring-boot ssl jetty jetty-9


    【解决方案1】:

    仅更改版本字符串是不够的。

    你还需要...

    • ALPNServerConnectionFactory - 用于处理选择 HTTP/2 协议的 TLS 层(称为 ALPN)
    • HTTP2ServerConnectionFactory - 用于使用 HTTP/2 协议

    embedded / Http2Server.java example中所见

    关键是将连接类型链接在一起,ALPN 到 HTTP2 到 HTTPS。

    // SSL Context Factory for HTTPS and HTTP/2
    SslContextFactory sslContextFactory = new SslContextFactory.Server();
    // configure sslContextFactory
    
    // HTTPS Configuration
    HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
    httpsConfig.addCustomizer(new SecureRequestCustomizer());
    
    // HTTP/2 Connection Factory
    HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
    
    ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
    alpn.setDefaultProtocol(http.getDefaultProtocol());
    
    // SSL Connection Factory
    SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
    
    // HTTP/2 Connector
    ServerConnector http2Connector =
        new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig));
    http2Connector.setPort(securePort);
    server.addConnector(http2Connector);
    

    【讨论】:

    • 链接有效,但是用jetty将spring boot项目升级到http2真是头疼。不得不将 java 升级到 java 11,然后不得不跳过箍。我开始质疑我是否应该像我这样的粉丝一样继续坚持码头。
    • Java 8u252+ 也支持内置的 ALPN。但建议升级到 Java 11。
    猜你喜欢
    • 2015-09-10
    • 2015-06-06
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多