Skip to content

Commit

Permalink
Issue #4443 - Track backport of ALPN APIs to Java 8.
Browse files Browse the repository at this point in the history
Modified jetty-alpn-openjdk8-* classes to support both
pre 8u252 (via alpn-boot) and post 8u252 (via standard API).

Modified build to work with 8u252 without requiring
bootclasspath during test execution.

Signed-off-by: Simone Bordet <[email protected]>
  • Loading branch information
sbordet committed Mar 3, 2020
1 parent 1ee8c8a commit ef9b1fe
Show file tree
Hide file tree
Showing 66 changed files with 559 additions and 182 deletions.
2 changes: 1 addition & 1 deletion examples/embedded/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
<profile>
<id>jdk9</id>
<activation>
<jdk>[1.9,)</jdk>
<jdk>[9,)</jdk>
</activation>
<dependencies>
<dependency>
Expand Down
5 changes: 0 additions & 5 deletions jetty-alpn/jetty-alpn-java-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
Expand Down
1 change: 1 addition & 0 deletions jetty-alpn/jetty-alpn-openjdk8-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@

package org.eclipse.jetty.alpn.openjdk8.client;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;

import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.client.ALPNClientConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
Expand All @@ -33,11 +40,28 @@ public class OpenJDK8ClientALPNProcessor implements ALPNProcessor.Client
{
private static final Logger LOG = Log.getLogger(OpenJDK8ClientALPNProcessor.class);

private Method alpnProtocols;
private Method alpnProtocol;

@Override
public void init()
{
if (JavaVersion.VERSION.getPlatform() != 8)
throw new IllegalStateException(this + " not applicable for java " + JavaVersion.VERSION);

try
{
// JDK 8u252 has the JDK 9 ALPN API backported.
// Use reflection so we can build with a JDK version less than 8u252.
alpnProtocols = SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
alpnProtocol = SSLEngine.class.getMethod("getApplicationProtocol");
return;
}
catch (NoSuchMethodException ignored)
{
}

// Backported ALPN APIs not available.
if (ALPN.class.getClassLoader() != null)
throw new IllegalStateException(ALPN.class.getName() + " must be on JVM boot classpath");
if (LOG.isDebugEnabled())
Expand All @@ -53,14 +77,34 @@ public boolean appliesTo(SSLEngine sslEngine)
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
connection.addListener(new ALPNListener((ALPNClientConnection)connection));
ALPNClientConnection alpnConnection = (ALPNClientConnection)connection;
if (alpnProtocols == null)
{
connection.addListener(new ALPNConnectionListener(alpnConnection));
}
else
{
try
{
Object protocols = alpnConnection.getProtocols().toArray(new String[0]);
SSLParameters sslParameters = sslEngine.getSSLParameters();
alpnProtocols.invoke(sslParameters, protocols);
sslEngine.setSSLParameters(sslParameters);
((SslConnection.DecryptedEndPoint)connection.getEndPoint()).getSslConnection()
.addHandshakeListener(new ALPNSSLListener(alpnConnection));
}
catch (IllegalAccessException | InvocationTargetException x)
{
throw new IllegalStateException(this + " unable to set ALPN protocols", x);
}
}
}

private final class ALPNListener implements ALPN.ClientProvider, Connection.Listener
private static final class ALPNConnectionListener implements ALPN.ClientProvider, Connection.Listener
{
private final ALPNClientConnection alpnConnection;

private ALPNListener(ALPNClientConnection connection)
private ALPNConnectionListener(ALPNClientConnection connection)
{
alpnConnection = connection;
}
Expand Down Expand Up @@ -102,4 +146,32 @@ public void selected(String protocol)
alpnConnection.selected(protocol);
}
}

private final class ALPNSSLListener implements SslHandshakeListener
{
private final ALPNClientConnection alpnConnection;

private ALPNSSLListener(ALPNClientConnection connection)
{
alpnConnection = connection;
}

@Override
public void handshakeSucceeded(Event event) throws SSLException
{
try
{
SSLEngine sslEngine = alpnConnection.getSSLEngine();
String protocol = (String)alpnProtocol.invoke(sslEngine);
if (LOG.isDebugEnabled())
LOG.debug("selected protocol {}", protocol);
alpnConnection.selected(protocol);
}
catch (IllegalAccessException | InvocationTargetException x)
{
SSLHandshakeException failure = new SSLHandshakeException(this + " unable to get ALPN protocol");
throw (SSLHandshakeException)failure.initCause(x);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@

package org.eclipse.jetty.alpn.openjdk8.server;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;

import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.server.ALPNServerConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
Expand All @@ -35,11 +39,26 @@ public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
{
private static final Logger LOG = Log.getLogger(OpenJDK8ServerALPNProcessor.class);

private Method alpnSelector;

@Override
public void init()
{
if (JavaVersion.VERSION.getPlatform() != 8)
throw new IllegalStateException(this + " not applicable for java " + JavaVersion.VERSION);

try
{
// JDK 8u252 has the JDK 9 ALPN API backported.
// Use reflection so we can build with a JDK version less than 8u252.
alpnSelector = SSLEngine.class.getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
return;
}
catch (NoSuchMethodException ignored)
{
}

// Backported ALPN APIs not available.
if (ALPN.class.getClassLoader() != null)
throw new IllegalStateException(ALPN.class.getName() + " must be on JVM boot classpath");
if (LOG.isDebugEnabled())
Expand All @@ -55,10 +74,26 @@ public boolean appliesTo(SSLEngine sslEngine)
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
connection.addListener(new ALPNListener((ALPNServerConnection)connection));
if (alpnSelector == null)
{
ALPNListener listener = new ALPNListener((ALPNServerConnection)connection);
connection.addListener(listener);
}
else
{
try
{
ALPNCallback callback = new ALPNCallback((ALPNServerConnection)connection);
alpnSelector.invoke(sslEngine, callback);
}
catch (IllegalAccessException | InvocationTargetException x)
{
throw new IllegalStateException(this + " unable to set ALPN selector", x);
}
}
}

private final class ALPNListener implements ALPN.ServerProvider, Connection.Listener
private static final class ALPNListener implements ALPN.ServerProvider, Connection.Listener
{
private final ALPNServerConnection alpnConnection;

Expand Down Expand Up @@ -92,12 +127,58 @@ public void unsupported()
}

@Override
public String select(List<String> protocols) throws SSLException
public String select(List<String> protocols)
{
if (LOG.isDebugEnabled())
LOG.debug("select {} {}", alpnConnection, protocols);
alpnConnection.select(protocols);
return alpnConnection.getProtocol();
}
}

private static class ALPNCallback implements BiFunction<SSLEngine, List<String>, String>, SslHandshakeListener
{
private final ALPNServerConnection alpnConnection;

private ALPNCallback(ALPNServerConnection connection)
{
alpnConnection = connection;
((SslConnection.DecryptedEndPoint)alpnConnection.getEndPoint()).getSslConnection().addHandshakeListener(this);
}

@Override
public String apply(SSLEngine engine, List<String> protocols)
{
try
{
if (LOG.isDebugEnabled())
LOG.debug("apply {} {}", alpnConnection, protocols);
alpnConnection.select(protocols);
return alpnConnection.getProtocol();
}
catch (Throwable x)
{
// Cannot negotiate the protocol, return null to have
// JSSE send Alert.NO_APPLICATION_PROTOCOL to the client.
return null;
}
}

@Override
public void handshakeSucceeded(Event event)
{
String protocol = alpnConnection.getProtocol();
if (LOG.isDebugEnabled())
LOG.debug("TLS handshake succeeded, protocol={} for {}", protocol, alpnConnection);
if (protocol == null)
alpnConnection.unsupported();
}

@Override
public void handshakeFailed(Event event, Throwable failure)
{
if (LOG.isDebugEnabled())
LOG.debug("TLS handshake failed " + alpnConnection, failure);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.10.v20161026|lib/alpn/alpn-boot-8.1.10.v20161026.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[depend]
alpn-8-boot

[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar

Expand Down
Loading

0 comments on commit ef9b1fe

Please sign in to comment.