Add support for HTTP/2 in Jetty with Conscrypt
This commit configures Jetty for HTTP/2 support as soon as the following conditions are met: * `server.http2.enabled=true` * Both `org.eclipse.jetty:jetty-alpn-conscrypt-server` and `org.eclipse.jetty.http2:http2-server` are on classpath This will use the Conscrypt library for ALPN and TLS support using native libraries shipped within the Conscrypt uber Jar. This does not require a JVM agent or patching the JDK classes. Closes gh-10902
This commit is contained in:
parent
ea70b2ed2e
commit
3ab32df242
|
|
@ -1595,304 +1595,16 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>apache-jstl</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-java-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-java-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ant</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-hazelcast</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-infinispan</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jaas</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-nosql</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-proxy</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-quickstart</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-runner</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-spring</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-start</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-unixsocket</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util-ajax</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-xml</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>cdi-core</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>cdi-servlet</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.gcloud</groupId>
|
||||
<artifactId>jetty-gcloud-session-manager</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-hpack</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.memcached</groupId>
|
||||
<artifactId>jetty-memcached-sessions</artifactId>
|
||||
<artifactId>jetty-bom</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.orbit</groupId>
|
||||
<artifactId>javax.servlet.jsp</artifactId>
|
||||
<version>${jetty-jsp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-jsp</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-warurl</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-httpservice</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>javax-websocket-client-impl</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>javax-websocket-server-impl</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-api</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-client</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-servlet</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
|
|
|
|||
|
|
@ -170,6 +170,16 @@
|
|||
<artifactId>jetty-webapp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-conscrypt-server</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -98,7 +98,10 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
|||
contextHandler.addServlet(servletHolder, "/");
|
||||
JettyReactiveWebServerFactory.logger
|
||||
.info("Server initialized with port: " + port);
|
||||
new SslServerCustomizer(port, getSsl(), getSslStoreProvider()).customize(server);
|
||||
if (getSsl() != null && getSsl().isEnabled()) {
|
||||
new SslServerCustomizer(port, getSsl(), getSslStoreProvider(),
|
||||
getHttp2()).customize(server);
|
||||
}
|
||||
for (JettyServerCustomizer customizer : getServerCustomizers()) {
|
||||
customizer.customize(server);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -152,7 +152,10 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
configureWebAppContext(context, initializers);
|
||||
server.setHandler(addHandlerWrappers(context));
|
||||
this.logger.info("Server initialized with port: " + port);
|
||||
new SslServerCustomizer(port, getSsl(), getSslStoreProvider()).customize(server);
|
||||
if (getSsl() != null && getSsl().isEnabled()) {
|
||||
new SslServerCustomizer(port, getSsl(), getSslStoreProvider(),
|
||||
getHttp2()).customize(server);
|
||||
}
|
||||
for (JettyServerCustomizer customizer : getServerCustomizers()) {
|
||||
customizer.customize(server);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -19,8 +19,10 @@ package org.springframework.boot.web.embedded.jetty;
|
|||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.http2.HTTP2Cipher;
|
||||
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
|
|
@ -31,9 +33,12 @@ import org.eclipse.jetty.server.SslConnectionFactory;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
import org.springframework.boot.web.server.Http2;
|
||||
import org.springframework.boot.web.server.Ssl;
|
||||
import org.springframework.boot.web.server.SslStoreProvider;
|
||||
import org.springframework.boot.web.server.WebServerException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
|
|
@ -41,6 +46,7 @@ import org.springframework.util.ResourceUtils;
|
|||
* {@link JettyServerCustomizer} that configures SSL on the given Jetty server instance.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Olivier Lamy
|
||||
*/
|
||||
class SslServerCustomizer implements JettyServerCustomizer {
|
||||
|
||||
|
|
@ -50,37 +56,76 @@ class SslServerCustomizer implements JettyServerCustomizer {
|
|||
|
||||
private final SslStoreProvider sslStoreProvider;
|
||||
|
||||
SslServerCustomizer(int port, Ssl ssl, SslStoreProvider sslStoreProvider) {
|
||||
private final Http2 http2;
|
||||
|
||||
SslServerCustomizer(int port, Ssl ssl, SslStoreProvider sslStoreProvider, Http2 http2) {
|
||||
this.port = port;
|
||||
this.ssl = ssl;
|
||||
this.sslStoreProvider = sslStoreProvider;
|
||||
this.http2 = http2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(Server server) {
|
||||
if (this.ssl != null && this.ssl.isEnabled()) {
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
configureSsl(sslContextFactory, this.ssl, this.sslStoreProvider);
|
||||
AbstractConnector connector = createSslConnector(server, sslContextFactory,
|
||||
this.port);
|
||||
server.setConnectors(new Connector[] { connector });
|
||||
}
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
configureSsl(sslContextFactory, this.ssl, this.sslStoreProvider);
|
||||
ServerConnector connector = createConnector(server, sslContextFactory,
|
||||
this.port);
|
||||
server.setConnectors(new Connector[] {connector});
|
||||
}
|
||||
|
||||
private AbstractConnector createSslConnector(Server server,
|
||||
SslContextFactory sslContextFactory, int port) {
|
||||
private ServerConnector createConnector(Server server, SslContextFactory sslContextFactory, int port) {
|
||||
HttpConfiguration config = new HttpConfiguration();
|
||||
config.setSendServerVersion(false);
|
||||
config.setSecureScheme("https");
|
||||
config.setSecurePort(port);
|
||||
config.addCustomizer(new SecureRequestCustomizer());
|
||||
ServerConnector connector;
|
||||
if (this.http2 != null && this.http2.getEnabled()) {
|
||||
final boolean isAlpnPresent = ClassUtils
|
||||
.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory",
|
||||
getClass().getClassLoader());
|
||||
Assert.state(isAlpnPresent,
|
||||
() -> "The 'org.eclipse.jetty:jetty-alpn-server' " +
|
||||
"dependency is required for HTTP/2 support.");
|
||||
final boolean isConscryptPresent = ClassUtils
|
||||
.isPresent("org.conscrypt.Conscrypt", getClass().getClassLoader());
|
||||
Assert.state(isConscryptPresent,
|
||||
() -> "The 'org.eclipse.jetty.http2:http2-server' and Conscrypt " +
|
||||
"dependencies are required for HTTP/2 support.");
|
||||
connector = createHttp2Connector(server, config, sslContextFactory);
|
||||
}
|
||||
else {
|
||||
connector = createSslConnector(server, config, sslContextFactory);
|
||||
}
|
||||
connector.setPort(port);
|
||||
return connector;
|
||||
}
|
||||
|
||||
private ServerConnector createSslConnector(Server server, HttpConfiguration config,
|
||||
SslContextFactory sslContextFactory) {
|
||||
HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config);
|
||||
SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(
|
||||
sslContextFactory, HttpVersion.HTTP_1_1.asString());
|
||||
ServerConnector serverConnector = new ServerConnector(server,
|
||||
sslConnectionFactory, connectionFactory);
|
||||
serverConnector.setPort(port);
|
||||
return serverConnector;
|
||||
}
|
||||
|
||||
private ServerConnector createHttp2Connector(Server server, HttpConfiguration config,
|
||||
SslContextFactory sslContextFactory) {
|
||||
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(config);
|
||||
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
|
||||
alpn.setDefaultProtocol("h2");
|
||||
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
|
||||
sslContextFactory.setProvider("Conscrypt");
|
||||
SslConnectionFactory ssl = new SslConnectionFactory(
|
||||
sslContextFactory, alpn.getProtocol());
|
||||
ServerConnector http2Connector = new ServerConnector(
|
||||
server, ssl, alpn, h2, new HttpConnectionFactory(config));
|
||||
return http2Connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the SSL connection.
|
||||
* @param factory the Jetty {@link SslContextFactory}.
|
||||
|
|
|
|||
Loading…
Reference in New Issue