WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

HTTP/2

Jetty 9.3.x supports HTTP/2. To get HTTP/2 up and running requires a small amount of work, mainly due to the requirements for TLS/SSL.

The following recipe makes configuring your HTTP stack with HTTP/2 relatively painless...

1. Get a TLS Certificate and Keystore

You will need a TLS certificate in a keystore. The details of how to install an official certificate (or for development, just create a self-signed certificate) are documented here...

http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html

The thing to take care of is that the certificate alias is jetty.

If you're using a CA you'll also need to make sure you have the necessary certificate signing chain in the keystore - in my experience this is the most likely cause of problems in setting up TLS/SSL.

2. ALPN Boot

If you're running Java 9 you can (hopefully) ignore this step.

Java 8 doesn't understand the ALPN protocol negotiation in its TLS implementation so you must provide this capability. You will need to provide an ALPN implementation library for your specific JVM version.

You can find which version of alpn-boot-xxxx.jar you need using the table here...

https://www.eclipse.org/jetty/documentation/9.3.x/alpn-chapter.html

When you know the version you can download the jar file here...

http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/

Due to the low-level javax.security.xxxx packages that it provides you need to register it in the low-level Java classloader. You can do this by setting an extension in your NK install's bin/jvmsettings.cnf

Add the following:

-Xbootclasspath/p:/the/directory/path/where/you/put/alpn-boot-xxxxxx.jar

(jvmsettings.cnf is a single line of switches to the java process - so keep it all on one line)

3. Tell Jetty to use an HTTP/2 connector

You can download a ready to use pre-configured example of the HTTPServerConfig.xml here.

Here's the details of how to configure Jetty with the HTTP2 connection factory.

Find your Frontend Fulcrum (FEF) module in modules/urn.org.netkernel.fulcrum.frontend-x.x.x/ and edit etc/HTTPServerConfig.xml

Add the SSL ServerConnector with a list of factories: SslConnectionFactory, ALPNServerConnectionFactory, HTTP2ServerConnectionFactory and, for HTTP/1.1 fallback, HttpConnectionFactory.

Note, the SslConnectionFactory must have its "next" argument set to "alpn" - which hooks in the protocol negotiation at the TLS level.

<Configure>
  <!-- =========================================================== -->
  <!-- Add a SSL Connector with 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">
            <Item>
              <New class="org.eclipse.jetty.server.SslConnectionFactory">
                <Arg name="next">alpn</Arg>
                <Arg name="sslContextFactory">
                  <Ref refid="sslContextFactory" />
                </Arg>
              </New>
            </Item>
            <Item>
              <New id="alpn" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">
                <Arg type="String">
                  <Property name="jetty.alpn.protocols" deprecated="alpn.protocols" default="" />
                </Arg>
                <Set name="defaultProtocol">
                  <Property name="jetty.alpn.defaultProtocol" deprecated="alpn.defaultProtocol" />
                </Set>
              </New>
            </Item>
            <Item>
              <New class="org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory">
                <Arg name="config">
                  <Ref refid="sslHttpConfig" />
                </Arg>
                <Set name="maxConcurrentStreams">
                  <Property name="jetty.http2.maxConcurrentStreams" deprecated="http2.maxConcurrentStreams" default="1024" />
                </Set>
                <Set name="initialStreamSendWindow">
                  <Property name="jetty.http2.initialStreamSendWindow" default="65535" />
                </Set>
              </New>
            </Item>
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config">
                  <Ref refid="sslHttpConfig" />
                </Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="name">Frontend SSL Fulcrum: 8443</Set>
        <Set name="host">
          <SystemProperty name="netkernel.http.frontend.host" default="0.0.0.0" />
        </Set>
        <Set name="port">
          <Property name="netkernel.http.frontend.secure.port" default="8443" />
        </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="acceptQueueSize">
          <Property name="ssl.acceptQueueSize" default="0" />
        </Set>
        <!-- Enable Connector Statistics -->
        <Call name="addBean">
          <Arg>
            <New id="ConnectorStatistics" class="org.eclipse.jetty.server.ConnectorStatistics" />
          </Arg>
        </Call>
      </New>
    </Arg>
  </Call>
  <Ref refid="sslContextFactory">
    <Set name="CipherComparator">
      <Get class="org.eclipse.jetty.http2.HTTP2Cipher" name="COMPARATOR" />
    </Set>
    <Set name="useCipherSuitesOrder">true</Set>
  </Ref>
</Configure>

When you first set up ALPN its a good idea to enable debugging messages - so you can observe the protocol negotiation...

<Set class="org.eclipse.jetty.alpn.ALPN" name="debug" type="boolean">
  <Property name="jetty.alpn.debug" default="true" />
</Set>

5. Testing

If you have Jetty's TLS stack correctly configured you'll see the following log message when NetKernel starts the HTTP transport...

I 10:57:39 HTTPTranspor~ Starting [Frontend SSL Fulcrum: 8443] with protocol(s) [ssl, alpn, h2, h2-17, h2-16, h2-15, h2-14, http/1.1]

The list of protocols must show alpn and h2.

All being well, if you've got an application deployed to the FEF it will now "just work" when you request it down the https://localhost:8443/xxxx path.

Fortunately there are absolutely no consequences in using HTTP/2 to an existing application at either client or server-side. If your browser supports it - your page requests will get multiplexed, if it doesn't then you'll default back to plain old HTTP/1.1. In either case the server-side logical ROC requests will arrive with exactly the same context as before.

One thing to note is that, because HTTP/2 is a low level protocol update, your browser's developer tools such as Firebug will not show any difference in the HTTP network request view (other than speed!). So how do you know if you've got it set up right?

Fortunately Chrome has a built-in HTTP/2 diagnostics tool. Open up a tab and paste this URL in...

chrome://net-internals/#http2

You can then observe and capture HTTP/2 traffic to verify your solution is working as you intended.

Reference

If you need help configuring your HTTP stack please get in touch with 1060 Research support.