diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index ddf1bf8c7a..729f431f45 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -1595,304 +1595,16 @@ org.eclipse.jetty - apache-jsp - ${jetty.version} - - - org.eclipse.jetty - apache-jstl - ${jetty.version} - - - org.eclipse.jetty - jetty-alpn-client - ${jetty.version} - - - org.eclipse.jetty - jetty-alpn-java-client - ${jetty.version} - - - org.eclipse.jetty - jetty-alpn-java-server - ${jetty.version} - - - org.eclipse.jetty - jetty-alpn-server - ${jetty.version} - - - org.eclipse.jetty - jetty-annotations - ${jetty.version} - - - org.eclipse.jetty - jetty-ant - ${jetty.version} - - - org.eclipse.jetty - jetty-client - ${jetty.version} - - - org.eclipse.jetty - jetty-continuation - ${jetty.version} - - - org.eclipse.jetty - jetty-deploy - ${jetty.version} - - - org.eclipse.jetty - jetty-hazelcast - ${jetty.version} - - - org.eclipse.jetty - jetty-http - ${jetty.version} - - - org.eclipse.jetty - jetty-http-spi - ${jetty.version} - - - org.eclipse.jetty - jetty-infinispan - ${jetty.version} - - - org.eclipse.jetty - jetty-io - ${jetty.version} - - - org.eclipse.jetty - jetty-jaas - ${jetty.version} - - - org.eclipse.jetty - jetty-jaspi - ${jetty.version} - - - org.eclipse.jetty - jetty-jmx - ${jetty.version} - - - org.eclipse.jetty - jetty-jndi - ${jetty.version} - - - org.eclipse.jetty - jetty-nosql - ${jetty.version} - - - org.eclipse.jetty - jetty-plus - ${jetty.version} - - - org.eclipse.jetty - jetty-proxy - ${jetty.version} - - - org.eclipse.jetty - jetty-quickstart - ${jetty.version} - - - org.eclipse.jetty - jetty-rewrite - ${jetty.version} - - - org.eclipse.jetty - jetty-runner - ${jetty.version} - - - org.eclipse.jetty - jetty-security - ${jetty.version} - - - org.eclipse.jetty - jetty-server - ${jetty.version} - - - org.eclipse.jetty - jetty-servlet - ${jetty.version} - - - org.eclipse.jetty - jetty-servlets - ${jetty.version} - - - org.eclipse.jetty - jetty-spring - ${jetty.version} - - - org.eclipse.jetty - jetty-start - ${jetty.version} - - - org.eclipse.jetty - jetty-unixsocket - ${jetty.version} - - - org.eclipse.jetty - jetty-util - ${jetty.version} - - - org.eclipse.jetty - jetty-util-ajax - ${jetty.version} - - - org.eclipse.jetty - jetty-webapp - ${jetty.version} - - - org.eclipse.jetty - jetty-xml - ${jetty.version} - - - org.eclipse.jetty.cdi - cdi-core - ${jetty.version} - - - org.eclipse.jetty.cdi - cdi-servlet - ${jetty.version} - - - org.eclipse.jetty.fcgi - fcgi-client - ${jetty.version} - - - org.eclipse.jetty.fcgi - fcgi-server - ${jetty.version} - - - org.eclipse.jetty.gcloud - jetty-gcloud-session-manager - ${jetty.version} - - - org.eclipse.jetty.http2 - http2-client - ${jetty.version} - - - org.eclipse.jetty.http2 - http2-common - ${jetty.version} - - - org.eclipse.jetty.http2 - http2-hpack - ${jetty.version} - - - org.eclipse.jetty.http2 - http2-http-client-transport - ${jetty.version} - - - org.eclipse.jetty.http2 - http2-server - ${jetty.version} - - - org.eclipse.jetty.memcached - jetty-memcached-sessions + jetty-bom ${jetty.version} + import + pom org.eclipse.jetty.orbit javax.servlet.jsp ${jetty-jsp.version} - - org.eclipse.jetty.osgi - jetty-osgi-boot - ${jetty.version} - - - org.eclipse.jetty.osgi - jetty-osgi-boot-jsp - ${jetty.version} - - - org.eclipse.jetty.osgi - jetty-osgi-boot-warurl - ${jetty.version} - - - org.eclipse.jetty.osgi - jetty-httpservice - ${jetty.version} - - - org.eclipse.jetty.websocket - javax-websocket-client-impl - ${jetty.version} - - - org.eclipse.jetty.websocket - javax-websocket-server-impl - ${jetty.version} - - - org.eclipse.jetty.websocket - websocket-api - ${jetty.version} - - - org.eclipse.jetty.websocket - websocket-client - ${jetty.version} - - - org.eclipse.jetty.websocket - websocket-common - ${jetty.version} - - - org.eclipse.jetty.websocket - websocket-server - ${jetty.version} - - - org.eclipse.jetty.websocket - websocket-servlet - ${jetty.version} - org.ehcache ehcache diff --git a/spring-boot-project/spring-boot/pom.xml b/spring-boot-project/spring-boot/pom.xml index 8654c69ba2..aff395bf3f 100644 --- a/spring-boot-project/spring-boot/pom.xml +++ b/spring-boot-project/spring-boot/pom.xml @@ -170,6 +170,16 @@ jetty-webapp true + + org.eclipse.jetty + jetty-alpn-conscrypt-server + true + + + org.eclipse.jetty.http2 + http2-server + true + org.hamcrest hamcrest-library diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java index 7214c5f339..83c2648c81 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java @@ -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); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java index 9ac427f3e1..dda3a565a0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java @@ -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); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java index b1a482874a..d34419d5d1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java @@ -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}.