Jump to: navigation, search

Difference between revisions of "Jetty/Feature/NPN"

< Jetty‎ | Feature
Line 8: Line 8:
 
| body =
 
| body =
  
==JVM Startup Usage==
+
===JVM Startup Usage===
  
 
In order to enable NPN support, you need to start the JVM with:
 
In order to enable NPN support, you need to start the JVM with:
Line 18: Line 18:
 
where <code>path_to_npn_boot_jar</code> is the path on file system for the NPN Boot jar file, for example one at the following Maven coordinates [http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot org.mortbay.jetty.npn:npn-boot].
 
where <code>path_to_npn_boot_jar</code> is the path on file system for the NPN Boot jar file, for example one at the following Maven coordinates [http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot org.mortbay.jetty.npn:npn-boot].
  
==API Usage==
+
===API Usage===
  
 
Applications needs to interact with the negotiation of the next protocol performed by the NPN TLS extension. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.
 
Applications needs to interact with the negotiation of the next protocol performed by the NPN TLS extension. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.
Line 28: Line 28:
 
Refer to [http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/npn/NextProtoNego.html <code>NextProtoNego</code> javadocs] and to the examples below for further details about client and server provider methods.
 
Refer to [http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/npn/NextProtoNego.html <code>NextProtoNego</code> javadocs] and to the examples below for further details about client and server provider methods.
  
===Client Example===
+
====Client Example====
  
 
<source lang="java">
 
<source lang="java">
Line 60: Line 60:
 
The example for <code>SSLEngine</code> is identical, and you just need to replace the <code>SSLSocket</code> instance with a <code>SSLEngine</code> instance.
 
The example for <code>SSLEngine</code> is identical, and you just need to replace the <code>SSLSocket</code> instance with a <code>SSLEngine</code> instance.
  
===Server Example===
+
====Server Example====
  
 
<source lang="java">
 
<source lang="java">
Line 87: Line 87:
 
The <code>NextProtoNego.ServerProvider</code> methods <code>unsupported()</code>, <code>protocols()</code> and <code>protocolSelected(String)</code> will be called by the NPN implementation, so that the server application can, respectively, know whether the client supports NPN, provide the list of protocols supported by the server, and know what is the protocol chosen by the client.
 
The <code>NextProtoNego.ServerProvider</code> methods <code>unsupported()</code>, <code>protocols()</code> and <code>protocolSelected(String)</code> will be called by the NPN implementation, so that the server application can, respectively, know whether the client supports NPN, provide the list of protocols supported by the server, and know what is the protocol chosen by the client.
  
==Implementation Details==
+
===Implementation Details===
  
 
The NPN implementation relies on modification of few OpenJDK classes and on few new classes that needs to live in the <code>sun.security.ssl</code> package.
 
The NPN implementation relies on modification of few OpenJDK classes and on few new classes that needs to live in the <code>sun.security.ssl</code> package.
Line 94: Line 94:
 
The <code>NextProtoNego</code> class is released under same license as the classes of the Jetty project.  
 
The <code>NextProtoNego</code> class is released under same license as the classes of the Jetty project.  
  
==Usage in Unit Tests==
+
===Usage in Unit Tests===
  
 
It is possible to write and run unit tests that make use of the NPN implementation.
 
It is possible to write and run unit tests that make use of the NPN implementation.
Line 125: Line 125:
 
</source>
 
</source>
  
==Debugging==
+
===Debugging===
 +
 
 +
Debug logging for the NPN implementation can be enabled in this way:
 +
 
 +
<source lang="java">
 +
NextProtoNego.debug = true;
 +
</source>
 +
 
 +
Since the <code>NextProtoNego</code> class is in the boot classpath, we chose to not use logging libraries in order to not override application's logging library choices, so the logging is performed directly on <code>System.err</code>.
  
 
}}
 
}}

Revision as of 05:17, 12 March 2012



Introduction

The Jetty project provides an implementation of the Next Protocol Negotiation TLS Extension (NPN) for OpenJDK 7 or greater.

Jetty's NPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the Servlet Container), and can be reused in any other Java network server.

Feature

JVM Startup Usage

In order to enable NPN support, you need to start the JVM with:

java -Xbootclasspath/p:<path_to_npn_boot_jar> ...

where path_to_npn_boot_jar is the path on file system for the NPN Boot jar file, for example one at the following Maven coordinates org.mortbay.jetty.npn:npn-boot.

API Usage

Applications needs to interact with the negotiation of the next protocol performed by the NPN TLS extension. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.

In order to provide this interaction, Jetty's NPN implementation provides an API to applications, hosted at Maven coordinates org.eclipse.jetty.npn:npn-api. This dependency needs to be declared as "provided", because it is already included in the npn-boot jar (see section above) and therefore will be available in the boot classpath.

The API is composed of a single class, org.eclipse.jetty.npn.NextProtoNego, and applications need to register instances of SSLSocket or SSLEngine with a ClientProvider or ServerProvider (depending on whether the application is a client or server application). Refer to NextProtoNego javadocs and to the examples below for further details about client and server provider methods.

Client Example

SSLContext sslContext = ...;
SSLSocket sslSocket = (SSLSocket)context.getSocketFactory()
        .createSocket("localhost", server.getLocalPort());
 
NextProtoNego.put(sslSocket, new NextProtoNego.ClientProvider()
{
    @Override
    public boolean supports()
    {
        return true;
    }
 
    @Override
    public void unsupported()
    {
    }
 
    @Override
    public String selectProtocol(List<String> protocols)
    {
        return protocols.get(0);
    }
});

The NextProtoNego.ClientProvider methods supports(), unsupported() and selectProtocol(List<String>) will be called by the NPN implementation, so that the client application can, respectively, decide whether to support NPN, whether the server supports NPN, and select one of the protocols supported by the server.

The example for SSLEngine is identical, and you just need to replace the SSLSocket instance with a SSLEngine instance.

Server Example

SSLSocket sslSocket = ...;
NextProtoNego.put(sslSocket, new NextProtoNego.ServerProvider()
{
    @Override
    public void unsupported()
    {
    }
 
    @Override
    public List<String> protocols()
    {
        return Arrays.asList("http/1.1");
    }
 
    @Override
    public void protocolSelected(String protocol)
    {
        System.out.println("Protocol Selected is: " + protocol);
    }
});

The NextProtoNego.ServerProvider methods unsupported(), protocols() and protocolSelected(String) will be called by the NPN implementation, so that the server application can, respectively, know whether the client supports NPN, provide the list of protocols supported by the server, and know what is the protocol chosen by the client.

Implementation Details

The NPN implementation relies on modification of few OpenJDK classes and on few new classes that needs to live in the sun.security.ssl package. These classes are released under the same GPLv2+exception license of OpenJDK.

The NextProtoNego class is released under same license as the classes of the Jetty project.

Usage in Unit Tests

It is possible to write and run unit tests that make use of the NPN implementation. The solution that we used with Maven is to specify an additional command line argument to the Surefire plugin:

<project ...>
 
  <properties>
    <npn-version>7.6.2.v20120308</npn-version>
  </properties>
 
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <argLine>-Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn-version}/npn-boot-${npn-version}.jar</argLine>
        </configuration>
      </plugin>
 
      ...
 
    </plugins>
  </build>
 
  ...
 
</project>

Debugging

Debug logging for the NPN implementation can be enabled in this way:

NextProtoNego.debug = true;

Since the NextProtoNego class is in the boot classpath, we chose to not use logging libraries in order to not override application's logging library choices, so the logging is performed directly on System.err.