mirror of https://github.com/grpc/grpc-java.git
Adding support for NPN fallback.
This takes some steps towards #525, but it won't be fixed until we officially support OpenSSL. This is due to the fact that ALPN->NPN fallback isn't supported with Jetty (since only one of the bootstrap plugins can be provided).
This commit is contained in:
parent
1b1c646ccd
commit
247ffb1377
|
|
@ -44,6 +44,7 @@ import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.STREAMING_R
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TESTCA;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TESTCA;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TLS;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TLS;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TRANSPORT;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TRANSPORT;
|
||||||
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.USE_DEFAULT_CIPHERS;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.WARMUP_DURATION;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.WARMUP_DURATION;
|
||||||
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_MAX_VALUE;
|
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_MAX_VALUE;
|
||||||
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_PRECISION;
|
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_PRECISION;
|
||||||
|
|
@ -325,7 +326,7 @@ public class AsyncClient {
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
ClientConfiguration.Builder configBuilder = ClientConfiguration.newBuilder(
|
ClientConfiguration.Builder configBuilder = ClientConfiguration.newBuilder(
|
||||||
ADDRESS, CHANNELS, OUTSTANDING_RPCS, CLIENT_PAYLOAD, SERVER_PAYLOAD,
|
ADDRESS, CHANNELS, OUTSTANDING_RPCS, CLIENT_PAYLOAD, SERVER_PAYLOAD,
|
||||||
TLS, TESTCA, TRANSPORT, DURATION, WARMUP_DURATION, DIRECTEXECUTOR,
|
TLS, TESTCA, USE_DEFAULT_CIPHERS, TRANSPORT, DURATION, WARMUP_DURATION, DIRECTEXECUTOR,
|
||||||
SAVE_HISTOGRAM, STREAMING_RPCS, FLOW_CONTROL_WINDOW);
|
SAVE_HISTOGRAM, STREAMING_RPCS, FLOW_CONTROL_WINDOW);
|
||||||
ClientConfiguration config;
|
ClientConfiguration config;
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ import io.netty.channel.ServerChannel;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -107,10 +108,17 @@ public class AsyncServer {
|
||||||
|
|
||||||
File cert = TestUtils.loadCert("server1.pem");
|
File cert = TestUtils.loadCert("server1.pem");
|
||||||
File key = TestUtils.loadCert("server1.key");
|
File key = TestUtils.loadCert("server1.key");
|
||||||
boolean useJdkSsl = config.transport == ServerConfiguration.Transport.NETTY_NIO;
|
SslContextBuilder sslContextBuilder = GrpcSslContexts.forServer(cert, key);
|
||||||
sslContext = GrpcSslContexts.forServer(cert, key)
|
if (config.transport == ServerConfiguration.Transport.NETTY_NIO) {
|
||||||
.sslProvider(useJdkSsl ? SslProvider.JDK : SslProvider.OPENSSL)
|
sslContextBuilder = GrpcSslContexts.configure(sslContextBuilder, SslProvider.JDK);
|
||||||
.build();
|
} else {
|
||||||
|
// Native transport with OpenSSL
|
||||||
|
sslContextBuilder = GrpcSslContexts.configure(sslContextBuilder, SslProvider.OPENSSL);
|
||||||
|
}
|
||||||
|
if (config.useDefaultCiphers) {
|
||||||
|
sslContextBuilder.ciphers(null);
|
||||||
|
}
|
||||||
|
sslContext = sslContextBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
final EventLoopGroup boss;
|
final EventLoopGroup boss;
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class ClientConfiguration implements Configuration {
|
||||||
Transport transport = Transport.NETTY_NIO;
|
Transport transport = Transport.NETTY_NIO;
|
||||||
boolean tls;
|
boolean tls;
|
||||||
boolean testca;
|
boolean testca;
|
||||||
|
boolean useDefaultCiphers;
|
||||||
boolean directExecutor;
|
boolean directExecutor;
|
||||||
SocketAddress address;
|
SocketAddress address;
|
||||||
int channels = 4;
|
int channels = 4;
|
||||||
|
|
@ -233,6 +234,13 @@ class ClientConfiguration implements Configuration {
|
||||||
config.testca = parseBoolean(value);
|
config.testca = parseBoolean(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
USE_DEFAULT_CIPHERS("", "Use the default JDK ciphers for TLS (Used to support Java 7).",
|
||||||
|
"" + DEFAULT.useDefaultCiphers) {
|
||||||
|
@Override
|
||||||
|
protected void setClientValue(ClientConfiguration config, String value) {
|
||||||
|
config.useDefaultCiphers = parseBoolean(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
TRANSPORT("STR", Transport.getDescriptionString(), DEFAULT.transport.name().toLowerCase()) {
|
TRANSPORT("STR", Transport.getDescriptionString(), DEFAULT.transport.name().toLowerCase()) {
|
||||||
@Override
|
@Override
|
||||||
protected void setClientValue(ClientConfiguration config, String value) {
|
protected void setClientValue(ClientConfiguration config, String value) {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TARGET_QPS;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TESTCA;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TESTCA;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TLS;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TLS;
|
||||||
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TRANSPORT;
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.TRANSPORT;
|
||||||
|
import static io.grpc.benchmarks.qps.ClientConfiguration.ClientParam.USE_DEFAULT_CIPHERS;
|
||||||
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_MAX_VALUE;
|
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_MAX_VALUE;
|
||||||
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_PRECISION;
|
import static io.grpc.benchmarks.qps.Utils.HISTOGRAM_PRECISION;
|
||||||
import static io.grpc.benchmarks.qps.Utils.newClientChannel;
|
import static io.grpc.benchmarks.qps.Utils.newClientChannel;
|
||||||
|
|
@ -85,7 +86,7 @@ public class OpenLoopClient {
|
||||||
public static void main(String... args) throws Exception {
|
public static void main(String... args) throws Exception {
|
||||||
ClientConfiguration.Builder configBuilder = ClientConfiguration.newBuilder(
|
ClientConfiguration.Builder configBuilder = ClientConfiguration.newBuilder(
|
||||||
ADDRESS, TARGET_QPS, CLIENT_PAYLOAD, SERVER_PAYLOAD, TLS,
|
ADDRESS, TARGET_QPS, CLIENT_PAYLOAD, SERVER_PAYLOAD, TLS,
|
||||||
TESTCA, TRANSPORT, DURATION, SAVE_HISTOGRAM, FLOW_CONTROL_WINDOW);
|
TESTCA, USE_DEFAULT_CIPHERS, TRANSPORT, DURATION, SAVE_HISTOGRAM, FLOW_CONTROL_WINDOW);
|
||||||
ClientConfiguration config;
|
ClientConfiguration config;
|
||||||
try {
|
try {
|
||||||
config = configBuilder.build(args);
|
config = configBuilder.build(args);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class ServerConfiguration implements Configuration {
|
||||||
|
|
||||||
Transport transport = Transport.NETTY_NIO;
|
Transport transport = Transport.NETTY_NIO;
|
||||||
boolean tls;
|
boolean tls;
|
||||||
|
boolean useDefaultCiphers;
|
||||||
boolean directExecutor;
|
boolean directExecutor;
|
||||||
SocketAddress address;
|
SocketAddress address;
|
||||||
int flowControlWindow = NettyChannelBuilder.DEFAULT_FLOW_CONTROL_WINDOW;
|
int flowControlWindow = NettyChannelBuilder.DEFAULT_FLOW_CONTROL_WINDOW;
|
||||||
|
|
@ -172,6 +173,13 @@ class ServerConfiguration implements Configuration {
|
||||||
config.tls = parseBoolean(value);
|
config.tls = parseBoolean(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
USE_DEFAULT_CIPHERS("", "Use the default JDK ciphers for TLS (Used to support Java 7).",
|
||||||
|
"false") {
|
||||||
|
@Override
|
||||||
|
protected void setServerValue(ServerConfiguration config, String value) {
|
||||||
|
config.useDefaultCiphers = parseBoolean(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
TRANSPORT("STR", Transport.getDescriptionString(), DEFAULT.transport.name().toLowerCase()) {
|
TRANSPORT("STR", Transport.getDescriptionString(), DEFAULT.transport.name().toLowerCase()) {
|
||||||
@Override
|
@Override
|
||||||
protected void setServerValue(ServerConfiguration config, String value) {
|
protected void setServerValue(ServerConfiguration config, String value) {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import io.netty.channel.unix.DomainSocketAddress;
|
import io.netty.channel.unix.DomainSocketAddress;
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
|
||||||
import org.HdrHistogram.Histogram;
|
import org.HdrHistogram.Histogram;
|
||||||
|
|
@ -153,14 +154,21 @@ final class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's a Netty transport.
|
// It's a Netty transport.
|
||||||
SslContext context = null;
|
SslContext sslContext = null;
|
||||||
NegotiationType negotiationType = config.tls ? NegotiationType.TLS : NegotiationType.PLAINTEXT;
|
NegotiationType negotiationType = config.tls ? NegotiationType.TLS : NegotiationType.PLAINTEXT;
|
||||||
if (config.tls && config.testca) {
|
if (config.tls && config.testca) {
|
||||||
File cert = TestUtils.loadCert("ca.pem");
|
File cert = TestUtils.loadCert("ca.pem");
|
||||||
boolean useJdkSsl = config.transport == ClientConfiguration.Transport.NETTY_NIO;
|
SslContextBuilder sslContextBuilder = GrpcSslContexts.forClient().trustManager(cert);
|
||||||
context = GrpcSslContexts.forClient().trustManager(cert)
|
if (config.transport == ClientConfiguration.Transport.NETTY_NIO) {
|
||||||
.sslProvider(useJdkSsl ? SslProvider.JDK : SslProvider.OPENSSL)
|
sslContextBuilder = GrpcSslContexts.configure(sslContextBuilder, SslProvider.JDK);
|
||||||
.build();
|
} else {
|
||||||
|
// Native transport with OpenSSL
|
||||||
|
sslContextBuilder = GrpcSslContexts.configure(sslContextBuilder, SslProvider.OPENSSL);
|
||||||
|
}
|
||||||
|
if (config.useDefaultCiphers) {
|
||||||
|
sslContextBuilder.ciphers(null);
|
||||||
|
}
|
||||||
|
sslContext = sslContextBuilder.build();
|
||||||
}
|
}
|
||||||
final EventLoopGroup group;
|
final EventLoopGroup group;
|
||||||
final Class<? extends io.netty.channel.Channel> channelType;
|
final Class<? extends io.netty.channel.Channel> channelType;
|
||||||
|
|
@ -192,7 +200,7 @@ final class Utils {
|
||||||
.channelType(channelType)
|
.channelType(channelType)
|
||||||
.negotiationType(negotiationType)
|
.negotiationType(negotiationType)
|
||||||
.executor(config.directExecutor ? MoreExecutors.newDirectExecutorService() : null)
|
.executor(config.directExecutor ? MoreExecutors.newDirectExecutorService() : null)
|
||||||
.sslContext(context)
|
.sslContext(sslContext)
|
||||||
.flowControlWindow(config.flowControlWindow)
|
.flowControlWindow(config.flowControlWindow)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ subprojects {
|
||||||
// on the Java version.
|
// on the Java version.
|
||||||
def alpnboot_version = '8.1.2.v20141202'
|
def alpnboot_version = '8.1.2.v20141202'
|
||||||
if (JavaVersion.current().ordinal() < JavaVersion.VERSION_1_8.ordinal()) {
|
if (JavaVersion.current().ordinal() < JavaVersion.VERSION_1_8.ordinal()) {
|
||||||
alpnboot_version = '7.1.2.v20141202'
|
alpnboot_version = '7.1.3.v20150130'
|
||||||
}
|
}
|
||||||
|
|
||||||
alpnboot_package_name = 'org.mortbay.jetty.alpn:alpn-boot:' + alpnboot_version
|
alpnboot_package_name = 'org.mortbay.jetty.alpn:alpn-boot:' + alpnboot_version
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,14 @@
|
||||||
|
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import io.grpc.internal.ExperimentalApi;
|
||||||
import io.netty.handler.codec.http2.Http2SecurityUtil;
|
import io.netty.handler.codec.http2.Http2SecurityUtil;
|
||||||
import io.netty.handler.ssl.ApplicationProtocolConfig;
|
import io.netty.handler.ssl.ApplicationProtocolConfig;
|
||||||
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
|
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
|
||||||
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
|
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
|
||||||
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
|
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
|
||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
|
import io.netty.handler.ssl.SslProvider;
|
||||||
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
|
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -47,11 +49,25 @@ import java.io.File;
|
||||||
public class GrpcSslContexts {
|
public class GrpcSslContexts {
|
||||||
private GrpcSslContexts() {}
|
private GrpcSslContexts() {}
|
||||||
|
|
||||||
private static ApplicationProtocolConfig DEFAULT_APN = new ApplicationProtocolConfig(
|
private static String[] HTTP2_VERSIONS = {"h2"};
|
||||||
|
|
||||||
|
private static ApplicationProtocolConfig ALPN = new ApplicationProtocolConfig(
|
||||||
Protocol.ALPN,
|
Protocol.ALPN,
|
||||||
SelectorFailureBehavior.FATAL_ALERT,
|
SelectorFailureBehavior.FATAL_ALERT,
|
||||||
SelectedListenerFailureBehavior.FATAL_ALERT,
|
SelectedListenerFailureBehavior.FATAL_ALERT,
|
||||||
"h2");
|
HTTP2_VERSIONS);
|
||||||
|
|
||||||
|
private static ApplicationProtocolConfig NPN = new ApplicationProtocolConfig(
|
||||||
|
Protocol.NPN,
|
||||||
|
SelectorFailureBehavior.FATAL_ALERT,
|
||||||
|
SelectedListenerFailureBehavior.FATAL_ALERT,
|
||||||
|
HTTP2_VERSIONS);
|
||||||
|
|
||||||
|
private static ApplicationProtocolConfig NPN_AND_ALPN = new ApplicationProtocolConfig(
|
||||||
|
Protocol.NPN_AND_ALPN,
|
||||||
|
SelectorFailureBehavior.FATAL_ALERT,
|
||||||
|
SelectedListenerFailureBehavior.FATAL_ALERT,
|
||||||
|
HTTP2_VERSIONS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a SslContextBuilder with ciphers and APN appropriate for gRPC.
|
* Creates a SslContextBuilder with ciphers and APN appropriate for gRPC.
|
||||||
|
|
@ -89,7 +105,59 @@ public class GrpcSslContexts {
|
||||||
* an application requires particular settings it should override the options set here.
|
* an application requires particular settings it should override the options set here.
|
||||||
*/
|
*/
|
||||||
public static SslContextBuilder configure(SslContextBuilder builder) {
|
public static SslContextBuilder configure(SslContextBuilder builder) {
|
||||||
return builder.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
|
return configure(builder, defaultSslProvider());
|
||||||
.applicationProtocolConfig(DEFAULT_APN);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set ciphers and APN appropriate for gRPC. Precisely what is set is permitted to change, so if
|
||||||
|
* an application requires particular settings it should override the options set here.
|
||||||
|
*/
|
||||||
|
@ExperimentalApi
|
||||||
|
public static SslContextBuilder configure(SslContextBuilder builder, SslProvider provider) {
|
||||||
|
return builder.sslProvider(provider)
|
||||||
|
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
|
||||||
|
.applicationProtocolConfig(selectApplicationProtocolConfig(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns OpenSSL if available, otherwise returns the JDK provider.
|
||||||
|
*/
|
||||||
|
private static SslProvider defaultSslProvider() {
|
||||||
|
return SslProvider.JDK;
|
||||||
|
// TODO(nmittler): use this once we support OpenSSL.
|
||||||
|
// return OpenSsl.isAvailable() ? SslProvider.OPENSSL : SslProvider.JDK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to select the best {@link ApplicationProtocolConfig} for the given
|
||||||
|
* {@link SslProvider}.
|
||||||
|
*/
|
||||||
|
private static ApplicationProtocolConfig selectApplicationProtocolConfig(SslProvider provider) {
|
||||||
|
switch (provider) {
|
||||||
|
case JDK: {
|
||||||
|
if (JettyTlsUtil.isJettyAlpnConfigured()) {
|
||||||
|
return ALPN;
|
||||||
|
}
|
||||||
|
if (JettyTlsUtil.isJettyNpnConfigured()) {
|
||||||
|
return NPN;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Jetty ALPN/NPN has not been properly configured.");
|
||||||
|
}
|
||||||
|
case OPENSSL: {
|
||||||
|
throw new IllegalArgumentException("OpenSSL is not currently supported.");
|
||||||
|
// TODO(nmittler): use this once we support OpenSSL.
|
||||||
|
/*if (!OpenSsl.isAvailable()) {
|
||||||
|
throw new IllegalArgumentException("OpenSSL is not installed on the system.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpenSsl.isAlpnSupported()) {
|
||||||
|
return NPN_AND_ALPN;
|
||||||
|
} else {
|
||||||
|
return NPN;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported provider: " + provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,31 +32,33 @@
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that verifies that Jetty ALPN is properly configured for the system.
|
* Utility class for determining support for Jetty TLS ALPN/NPN.
|
||||||
*/
|
*/
|
||||||
final class JettyAlpnVerifier {
|
final class JettyTlsUtil {
|
||||||
private JettyAlpnVerifier() {
|
private JettyTlsUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when Jetty ALPN was not found in the boot classloader.
|
* Indicates whether or not the Jetty ALPN jar is installed in the boot classloader.
|
||||||
*/
|
*/
|
||||||
static final class NotFoundException extends Exception {
|
static boolean isJettyAlpnConfigured() {
|
||||||
public NotFoundException(Throwable cause) {
|
|
||||||
super("Jetty ALPN not found in boot classloader.", cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies that Jetty ALPN is configured properly on this system.
|
|
||||||
* @throws NotFoundException thrown if Jetty ALPN is missing from the boot classloader.
|
|
||||||
*/
|
|
||||||
static void verifyJettyAlpn() throws NotFoundException {
|
|
||||||
try {
|
try {
|
||||||
// Check the boot classloader for the ALPN class.
|
|
||||||
Class.forName("org.eclipse.jetty.alpn.ALPN", true, null);
|
Class.forName("org.eclipse.jetty.alpn.ALPN", true, null);
|
||||||
|
return true;
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new NotFoundException(e);
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the Jetty NPN jar is installed in the boot classloader.
|
||||||
|
*/
|
||||||
|
static boolean isJettyNpnConfigured() {
|
||||||
|
try {
|
||||||
|
Class.forName("org.eclipse.jetty.npn.NextProtoNego", true, null);
|
||||||
|
return true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,6 @@ import io.netty.handler.codec.http.HttpVersion;
|
||||||
import io.netty.handler.codec.http2.Http2ClientUpgradeCodec;
|
import io.netty.handler.codec.http2.Http2ClientUpgradeCodec;
|
||||||
import io.netty.handler.codec.http2.Http2ConnectionHandler;
|
import io.netty.handler.codec.http2.Http2ConnectionHandler;
|
||||||
import io.netty.handler.ssl.OpenSslContext;
|
import io.netty.handler.ssl.OpenSslContext;
|
||||||
import io.netty.handler.ssl.OpenSslEngine;
|
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
import io.netty.handler.ssl.SslHandler;
|
import io.netty.handler.ssl.SslHandler;
|
||||||
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
||||||
|
|
@ -74,15 +73,6 @@ public final class ProtocolNegotiators {
|
||||||
public static ChannelHandler serverTls(SSLEngine sslEngine) {
|
public static ChannelHandler serverTls(SSLEngine sslEngine) {
|
||||||
Preconditions.checkNotNull(sslEngine, "sslEngine");
|
Preconditions.checkNotNull(sslEngine, "sslEngine");
|
||||||
|
|
||||||
// If we're using Jetty ALPN, verify that it is configured properly.
|
|
||||||
if (!(sslEngine instanceof OpenSslEngine)) {
|
|
||||||
try {
|
|
||||||
JettyAlpnVerifier.verifyJettyAlpn();
|
|
||||||
} catch (JettyAlpnVerifier.NotFoundException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SslHandler(sslEngine, false);
|
return new SslHandler(sslEngine, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,24 +86,23 @@ public final class ProtocolNegotiators {
|
||||||
Preconditions.checkNotNull(sslContext, "sslContext");
|
Preconditions.checkNotNull(sslContext, "sslContext");
|
||||||
Preconditions.checkNotNull(inetAddress, "inetAddress");
|
Preconditions.checkNotNull(inetAddress, "inetAddress");
|
||||||
|
|
||||||
// If we're using Jetty ALPN, verify that it is configured properly.
|
|
||||||
if (!(sslContext instanceof OpenSslContext)) {
|
|
||||||
try {
|
|
||||||
JettyAlpnVerifier.verifyJettyAlpn();
|
|
||||||
} catch (JettyAlpnVerifier.NotFoundException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ProtocolNegotiator() {
|
return new ProtocolNegotiator() {
|
||||||
@Override
|
@Override
|
||||||
public Handler newHandler(Http2ConnectionHandler handler) {
|
public Handler newHandler(Http2ConnectionHandler handler) {
|
||||||
ChannelHandler sslBootstrap = new ChannelHandlerAdapter() {
|
ChannelHandler sslBootstrap = new ChannelHandlerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
|
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
final SSLEngine sslEngine;
|
||||||
|
if (sslContext instanceof OpenSslContext) {
|
||||||
// TODO(nmittler): Unsupported for OpenSSL in Netty < 4.1.Beta6.
|
// TODO(nmittler): Unsupported for OpenSSL in Netty < 4.1.Beta6.
|
||||||
SSLEngine sslEngine = sslContext.newEngine(ctx.alloc(),
|
// Until we upgrade Netty, uncomment the line below when testing with OpenSSL.
|
||||||
|
//sslEngine = sslContext.newEngine(ctx.alloc());
|
||||||
|
sslEngine = sslContext.newEngine(ctx.alloc(),
|
||||||
inetAddress.getHostName(), inetAddress.getPort());
|
inetAddress.getHostName(), inetAddress.getPort());
|
||||||
|
} else {
|
||||||
|
sslEngine = sslContext.newEngine(ctx.alloc(),
|
||||||
|
inetAddress.getHostName(), inetAddress.getPort());
|
||||||
|
}
|
||||||
SSLParameters sslParams = new SSLParameters();
|
SSLParameters sslParams = new SSLParameters();
|
||||||
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
|
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
|
||||||
sslEngine.setSSLParameters(sslParams);
|
sslEngine.setSSLParameters(sslParams);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue