使用 maven-jetty-plugin 启用 HTTP2

Posted

技术标签:

【中文标题】使用 maven-jetty-plugin 启用 HTTP2【英文标题】:Enable HTTP2 with maven-jetty-plugin 【发布时间】:2015-06-06 00:50:27 【问题描述】:

我已经使用码头启用了基于 SSL 的 HTTP/2 连接器。当我尝试连接浏览器时,出现“ERR_SSL_PROTOCOL_ERROR”错误。如果我切换到 HTTP/1.1 连接器,一切正常。

这是我的码头配置文件:

<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server"       -->
<!-- by adding a HTTP connector.                                   -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
        <Set name="secureScheme">https</Set>
        <Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
        <Set name="outputBufferSize">32768</Set>
        <Set name="requestHeaderSize">8192</Set>
        <Set name="responseHeaderSize">8192</Set>
        <Set name="sendServerVersion">true</Set>
        <Set name="sendDateHeader">false</Set>
        <Set name="headerCacheSize">512</Set>

        <!-- Uncomment to enable handling of X-Forwarded- style headers
        <Call name="addCustomizer">
          <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
        </Call>
        -->
    </New>

    <!-- =========================================================== -->
    <!-- Add a HTTP Connector.                                       -->
    <!-- Configure an o.e.j.server.ServerConnector with a single     -->
    <!-- HttpConnectionFactory instance using the common httpConfig  -->
    <!-- instance defined in jetty.xml                               -->
    <!--                                                             -->
    <!-- Consult the javadoc of o.e.j.server.ServerConnector and     -->
    <!-- o.e.j.server.HttpConnectionFactory for all configuration    -->
    <!-- that may be set here.                                       -->
    <!-- =========================================================== -->
    <Call name="addConnector">
        <Arg>
            <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server"><Ref refid="Server" /></Arg>
                <Arg name="acceptors" type="int"><Property name="http.acceptors" default="-1"/></Arg>
                <Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg>
                <Arg name="factories">
                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
                        <!-- uncomment to support proxy protocol
                    <Item>
                          <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
                        </Item>-->
                        <Item>
                            <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                                <Arg name="config"><Ref refid="httpConfig" /></Arg>
                            </New>
                        </Item>
                    </Array>
                </Arg>
                <Set name="host"><Property name="jetty.host" /></Set>
                <Set name="port"><Property name="jetty.port" default="8080" /></Set>
                <Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
                <Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set>
                <Set name="acceptorPriorityDelta"><Property name="http.acceptorPriorityDelta" default="0"/></Set>
                <Set name="selectorPriorityDelta"><Property name="http.selectorPriorityDelta" default="0"/></Set>
                <Set name="acceptQueueSize"><Property name="http.acceptQueueSize" default="0"/></Set>
            </New>
        </Arg>
    </Call>

</Configure>

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">

<!-- ============================================================= -->
<!-- Configure a HTTPS connector.                                  -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml.                                            -->
<!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">

    <!--Call name="addIfAbsentConnectionFactory">
        <Arg>
            <New class="org.eclipse.jetty.server.SslConnectionFactory">
                <Arg name="next">http/1.1</Arg>
                <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
            </New>
        </Arg>
    </Call>

    <Call name="addConnectionFactory">
        <Arg>
            <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
            </New>
        </Arg>
    </Call-->

    <!-- ============================================================= -->
    <!-- Configure a HTTP2 on the ssl connector.                       -->
    <!-- ============================================================= -->
    <Call name="addConnectionFactory">
        <Arg>
            <New class="org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory">
                <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
                <Set name="maxConcurrentStreams"><Property name="http2.maxConcurrentStreams" default="1024"/></Set>
            </New>
        </Arg>
    </Call>

</Configure>

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">

<!-- ============================================================= -->
<!-- Base SSL configuration                                        -->
<!-- This configuration needs to be used together with 1 or more   -->
<!-- of jetty-https.xml or jetty-http2.xml                         -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <!-- =========================================================== -->
    <!-- Create a TLS specific HttpConfiguration based on the        -->
    <!-- common HttpConfiguration defined in jetty.xml               -->
    <!-- Add a SecureRequestCustomizer to extract certificate and    -->
    <!-- session information                                         -->
    <!-- =========================================================== -->
    <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
        <Arg><Ref refid="httpConfig"/></Arg>
        <Call name="addCustomizer">
            <Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
        </Call>
    </New>

    <!-- =========================================================== -->
    <!-- Add a SSL Connector with no protocol factories              -->
    <!-- =========================================================== -->
    <Call  name="addConnector">
        <Arg>
            <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server"><Ref refid="Server" /></Arg>
                <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg>
                <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
                <Arg name="factories">
                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
                        <!-- uncomment to support proxy protocol
                    <Item>
                          <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
                        </Item>-->
                    </Array>
                </Arg>

                <Set name="host"><Property name="jetty.host" /></Set>
                <Set name="port"><Property name="ssl.port" default="443" /></Set>
                <Set name="port"><Property name="port" default="9090" /></Set>
                <Set name="idleTimeout"><Property name="ssl.timeout" default="30000"/></Set>
                <Set name="soLingerTime"><Property name="ssl.soLingerTime" default="-1"/></Set>
                <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set>
                <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set>
                <Set name="acceptQueueSize"><Property name="ssl.acceptQueueSize" default="0"/></Set>
            </New>
        </Arg>
    </Call>

    <!-- ============================================================= -->
    <!-- Create a TLS (SSL) Context Factory  for later reuse           -->
    <!-- ============================================================= -->
    <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
        <Set name="KeyStorePath"><Property name="jetty.base" default="../" />/<Property name="jetty.keystore" default="keystore.jks"/></Set>
        <Set name="KeyStorePassword"><Property name="jetty.keystore.password" default="storepwd"/></Set>
        <Set name="KeyManagerPassword"><Property name="jetty.keymanager.password" default="storepwd"/></Set>
        <Set name="TrustStorePath"><Property name="jetty.base" default="../" />/<Property name="jetty.truststore" default="truststore.jks"/></Set>
        <Set name="TrustStorePassword"><Property name="jetty.truststore.password" default="storepwd"/></Set>
        <Set name="EndpointIdentificationAlgorithm"></Set>
        <Set name="NeedClientAuth"><Property name="jetty.ssl.needClientAuth" default="false"/></Set>
        <Set name="WantClientAuth"><Property name="jetty.ssl.wantClientAuth" default="false"/></Set>
        <Set name="ExcludeCipherSuites">
            <Array type="String">
                <Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
                <Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
                <Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
                <Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
                <Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
                <Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
                <Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
            </Array>
        </Set>
    </New>
</Configure>

我正在使用 jetty-server、http2-server 和 jetty-alpn-server 工件版本 9.3.0.M1,是否需要添加任何其他依赖项?我正在使用JDK7。

谢谢

【问题讨论】:

【参考方案1】:

终于可以在 jetty 9.3.0 上使用了!我们需要确保 ALPN 配置良好并且我们使用 JDK8。

这是我为 maven-jetty-plugin 配置的:

<build>
    <finalName>$project.artifactId</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <verbose>true</verbose>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>$jetty-version</version>
            <configuration>
                <webAppSourceDirectory>$project.build.directory/$project.name</webAppSourceDirectory>
                <systemProperties>
                    <force>true</force>
                </systemProperties>
                <scanIntervalSeconds>10</scanIntervalSeconds>
                <webAppConfig>
                    <contextPath>/</contextPath>
                </webAppConfig>
                <jettyXml>../jetty.xml,../jetty-ssl.xml,../jetty-https.xml</jettyXml>
                <jvmArgs>-Xbootclasspath/p:$settings.localRepository/org/mortbay/jetty/alpn/alpn-boot/$alpn-version/alpn-boot-$alpn-version.jar</jvmArgs>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.eclipse.jetty.http2</groupId>
                    <artifactId>http2-server</artifactId>
                    <version>$jetty-version</version>
                </dependency>
                <dependency>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-alpn-server</artifactId>
                    <version>$jetty-version</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

<properties>
    <jetty-version>9.3.0.M2</jetty-version>
    <alpn-version>8.1.0.v20141016</alpn-version>
</properties>

根据JDK版本选择ALPN神器版本:http://eclipse.org/jetty/documentation/current/alpn-chapter.html

我还在 HTTP2ServerConnectionFactory 之前添加了这两个 ConnectioFactory

<Call name="addConnectionFactory">
    <Arg>
        <New class="org.eclipse.jetty.server.SslConnectionFactory">
            <Arg name="next">alpn</Arg>
            <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
        </New>
    </Arg>
</Call>

<Call name="addConnectionFactory">
    <Arg>
        <New id="alpn" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">
            <Arg type="String">
                <Property name="alpn.protocols" default="" />
            </Arg>
            <Set name="defaultProtocol">
                <Property name="alpn.defaultProtocol" />
            </Set>
        </New>
    </Arg>
</Call>

【讨论】:

以上是关于使用 maven-jetty-plugin 启用 HTTP2的主要内容,如果未能解决你的问题,请参考以下文章

今日出错解决cannot resolve plugin org.mortbay.jetty:maven-jetty-plugin阿里云仓库对应地址没有jetty插件

Maven中使用Jetty容器

端口被占用

配置jetty

Maven Jetty插件

idea jetty插件