diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java index 294ba9760a..7fd1c32697 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java @@ -193,10 +193,9 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa */ protected void logError(ServerRequest request, HttpStatus errorStatus) { if (errorStatus.is5xxServerError()) { - Throwable error = getError(request); - final String message = "Failed to handle request [" - + request.methodName() + " " + request.uri() + "]"; - logger.error(message, error); + Throwable ex = getError(request); + logger.error("Failed to handle request [" + request.methodName() + " " + + request.uri() + "]", ex); } } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index bbdfe67a6a..c44ca24d4a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -165,7 +165,7 @@ content into your application; rather pick only the properties that you need. server.error.include-stacktrace=never # When to include a "stacktrace" attribute. server.error.path=/error # Path of the error controller. server.error.whitelabel.enabled=true # Enable the default error page displayed in browsers in case of a server error. - server.http2.enabled=true # Enable HTTP/2 support if the current environment supports it. + server.http2.enabled=true # Whether to enable HTTP/2 support, if the current environment supports it. server.jetty.acceptors= # Number of acceptor threads to use. server.jetty.accesslog.append=false # Append to log. server.jetty.accesslog.date-format=dd/MMM/yyyy:HH:mm:ss Z # Timestamp format of the request log. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc index 9c9dc79391..99aa4c7b32 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -737,50 +737,51 @@ sample project for an example. [[howto-configure-http2]] === Configure HTTP/2 You can enable HTTP/2 support in your Spring Boot application with the -`+server.http2.enabled+` configuration property. This support depends on the -chosen web server and the application environment, since that protocol is not -supported out-of-the-box by JDK8. +`+server.http2.enabled+` configuration property. This support depends on the chosen web +server and the application environment, since that protocol is not supported +out-of-the-box by JDK8. [NOTE] ==== -Spring Boot does not support `h2c`, the cleartext version of the HTTP/2 -protocol. So you must configure <>. +Spring Boot does not support `h2c`, the cleartext version of the HTTP/2 protocol. So you +must configure <>. ==== Currently, only Undertow and Tomcat are supported with this configuration key. + [[howto-configure-http2-undertow]] ==== HTTP/2 with Undertow -As of Undertow 1.4.0+, HTTP/2 is supported without any additional requirement -on JDK8. +As of Undertow 1.4.0+, HTTP/2 is supported without any additional requirement on JDK8. + [[howto-configure-http2-tomcat]] ==== HTTP/2 with Tomcat -Spring Boot ships by default with Tomcat 8.5.x; with that version, -HTTP/2 is only supported if the `libtcnative` library and its dependencies -are installed on the host operating system. +Spring Boot ships by default with Tomcat 8.5.x; with that version, HTTP/2 is only +supported if the `libtcnative` library and its dependencies are installed on the host +operating system. -The library folder must be made available, if not already, to the JVM library -path; this can be done with a JVM argument such as +The library folder must be made available, if not already, to the JVM library path; this +can be done with a JVM argument such as `-Djava.library.path=/usr/local/opt/tomcat-native/lib`. More on this in the -http://tomcat.apache.org/tomcat-8.5-doc/apr.html[official Tomcat -documentation]. +http://tomcat.apache.org/tomcat-8.5-doc/apr.html[official Tomcat documentation]. Starting Tomcat 8.5.x without that native support will log the following error: [indent=0,subs="attributes"] ---- -ERROR 8787 --- [ main] o.a.coyote.http11.Http11NioProtocol : The upgrade handler [org.apache.coyote.http2.Http2Protocol] for [h2] only supports upgrade via ALPN but has been configured for the ["https-jsse-nio-8443"] connector that does not support ALPN. + ERROR 8787 --- [ main] o.a.coyote.http11.Http11NioProtocol : The upgrade handler [org.apache.coyote.http2.Http2Protocol] for [h2] only supports upgrade via ALPN but has been configured for the ["https-jsse-nio-8443"] connector that does not support ALPN. ---- -This error is not fatal, and the application starts with HTTP/1.1 SSL -support still. +This error is not fatal, and the application starts with HTTP/1.1 SSL support still. + +Running your application with Tomcat 9.0.x and JDK9 doesn't require any native library +installed. To use Tomcat 9, you can override the `tomcat.version` build property with the +version of your choice. + -Running your application with Tomcat 9.0.x and JDK9 doesn't require any native -library installed. To use Tomcat 9, you can override the `tomcat.version` -build property with the version of your choice. [[howto-configure-accesslogs]] === Configure Access Logging 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 d3354a08f1..dcc0d50db1 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 @@ -97,10 +97,9 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact ServletContextHandler contextHandler = new ServletContextHandler(server, "", false, false); contextHandler.addServlet(servletHolder, "/"); - this.logger.info("Server initialized with port: " + port); - SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(port, - getSsl(), getSslStoreProvider()); - sslServerCustomizer.customize(server); + JettyReactiveWebServerFactory.logger + .info("Server initialized with port: " + port); + new SslServerCustomizer(port, getSsl(), getSslStoreProvider()).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 8f221dd72b..5164e24fd6 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 @@ -153,9 +153,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor configureWebAppContext(context, initializers); server.setHandler(addHandlerWrappers(context)); this.logger.info("Server initialized with port: " + port); - SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(port, - getSsl(), getSslStoreProvider()); - sslServerCustomizer.customize(server); + new SslServerCustomizer(port, getSsl(), getSslStoreProvider()).customize(server); for (JettyServerCustomizer customizer : getServerCustomizers()) { customizer.customize(server); } @@ -167,7 +165,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor private Server createServer(InetSocketAddress address) { Server server = new Server(getThreadPool()); - server.setConnectors(new Connector[] {createConnector(address, server)}); + server.setConnectors(new Connector[] { createConnector(address, server) }); return server; } @@ -338,7 +336,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor context.getServletHandler().addServlet(holder); ServletMapping mapping = new ServletMapping(); mapping.setServletName("jsp"); - mapping.setPathSpecs(new String[] {"*.jsp", "*.jspx"}); + mapping.setPathSpecs(new String[] { "*.jsp", "*.jspx" }); context.getServletHandler().addServletMapping(mapping); } 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 022799e750..b1a482874a 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 @@ -38,8 +38,7 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.ResourceUtils; /** - * {@link JettyServerCustomizer} that configures SSL on the - * given Jetty server instance. + * {@link JettyServerCustomizer} that configures SSL on the given Jetty server instance. * * @author Brian Clozel */ @@ -88,7 +87,8 @@ class SslServerCustomizer implements JettyServerCustomizer { * @param ssl the ssl details. * @param sslStoreProvider the ssl store provider */ - protected void configureSsl(SslContextFactory factory, Ssl ssl, SslStoreProvider sslStoreProvider) { + protected void configureSsl(SslContextFactory factory, Ssl ssl, + SslStoreProvider sslStoreProvider) { factory.setProtocol(ssl.getProtocol()); configureSslClientAuth(factory, ssl); configureSslPasswords(factory, ssl); @@ -172,4 +172,5 @@ class SslServerCustomizer implements JettyServerCustomizer { factory.setTrustStoreProvider(ssl.getTrustStoreProvider()); } } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java index 81b93b0275..e9d1d64d74 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java @@ -24,14 +24,13 @@ import org.springframework.boot.web.server.Compression; import org.springframework.util.StringUtils; /** - * {@link TomcatConnectorCustomizer} that configures compression - * support on the given Connector. + * {@link TomcatConnectorCustomizer} that configures compression support on the given + * Connector. * * @author Brian Clozel */ class CompressionConnectorCustomizer implements TomcatConnectorCustomizer { - private final Compression compression; CompressionConnectorCustomizer(Compression compression) { @@ -43,18 +42,21 @@ class CompressionConnectorCustomizer implements TomcatConnectorCustomizer { if (this.compression != null && this.compression.getEnabled()) { ProtocolHandler handler = connector.getProtocolHandler(); if (handler instanceof AbstractHttp11Protocol) { - AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler; - Compression compression = this.compression; - protocol.setCompression("on"); - protocol.setCompressionMinSize(compression.getMinResponseSize()); - protocol.setCompressibleMimeType( - StringUtils.arrayToCommaDelimitedString(compression.getMimeTypes())); - if (this.compression.getExcludedUserAgents() != null) { - protocol.setNoCompressionUserAgents( - StringUtils.arrayToCommaDelimitedString( - this.compression.getExcludedUserAgents())); - } + customize((AbstractHttp11Protocol) handler); } } } + + private void customize(AbstractHttp11Protocol protocol) { + Compression compression = this.compression; + protocol.setCompression("on"); + protocol.setCompressionMinSize(compression.getMinResponseSize()); + protocol.setCompressibleMimeType( + StringUtils.arrayToCommaDelimitedString(compression.getMimeTypes())); + if (this.compression.getExcludedUserAgents() != null) { + protocol.setNoCompressionUserAgents(StringUtils.arrayToCommaDelimitedString( + this.compression.getExcludedUserAgents())); + } + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java index 9dac144cc9..e42111c75d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java @@ -33,8 +33,7 @@ import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; /** - * {@link TomcatConnectorCustomizer} that configures SSL support - * on the given connector. + * {@link TomcatConnectorCustomizer} that configures SSL support on the given connector. * * @author Brian Clozel */ @@ -56,8 +55,8 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer { Assert.state(handler instanceof AbstractHttp11JsseProtocol, "To use SSL, the connector's protocol handler must be an " + "AbstractHttp11JsseProtocol subclass"); - configureSsl((AbstractHttp11JsseProtocol) handler, - this.ssl, this.sslStoreProvider); + configureSsl((AbstractHttp11JsseProtocol) handler, this.ssl, + this.sslStoreProvider); connector.setScheme("https"); connector.setSecure(true); } @@ -68,8 +67,8 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer { * @param ssl the ssl details * @param sslStoreProvider the ssl store provider */ - protected void configureSsl(AbstractHttp11JsseProtocol protocol, - Ssl ssl, SslStoreProvider sslStoreProvider) { + protected void configureSsl(AbstractHttp11JsseProtocol protocol, Ssl ssl, + SslStoreProvider sslStoreProvider) { protocol.setSSLEnabled(true); protocol.setSslProtocol(ssl.getProtocol()); configureSslClientAuth(protocol, ssl); @@ -112,8 +111,7 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer { .getInstance(); instance.addUserFactory( new SslStoreProviderUrlStreamHandlerFactory(sslStoreProvider)); - protocol.setKeystoreFile( - SslStoreProviderUrlStreamHandlerFactory.KEY_STORE_URL); + protocol.setKeystoreFile(SslStoreProviderUrlStreamHandlerFactory.KEY_STORE_URL); protocol.setTruststoreFile( SslStoreProviderUrlStreamHandlerFactory.TRUST_STORE_URL); } @@ -153,4 +151,5 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer { protocol.setTruststoreProvider(ssl.getTrustStoreProvider()); } } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java index e2dfdf4561..067a875b76 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java @@ -20,6 +20,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.apache.catalina.Context; @@ -56,7 +57,8 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac private String protocol = DEFAULT_PROTOCOL; - private List contextLifecycleListeners = Arrays.asList(new AprLifecycleListener()); + private List contextLifecycleListeners = new ArrayList( + Collections.singleton(new AprLifecycleListener())); private List tomcatContextCustomizers = new ArrayList<>(); @@ -120,15 +122,11 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac * @param context the Tomcat context */ protected void configureContext(Context context) { - for (LifecycleListener lifecycleListener : this.contextLifecycleListeners) { - context.addLifecycleListener(lifecycleListener); - } - for (TomcatContextCustomizer customizer : this.tomcatContextCustomizers) { - customizer.customize(context); - } + this.contextLifecycleListeners.forEach(context::addLifecycleListener); + this.tomcatContextCustomizers + .forEach((customizer) -> customizer.customize(context)); } - // Needs to be protected so it can be used by subclasses protected void customizeConnector(Connector connector) { int port = (getPort() >= 0 ? getPort() : 0); connector.setPort(port); @@ -138,18 +136,13 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac if (connector.getProtocolHandler() instanceof AbstractProtocol) { customizeProtocol((AbstractProtocol) connector.getProtocolHandler()); } - - // If ApplicationContext is slow to start we want Tomcat not to bind to the socket - // prematurely... + // Don't bind to the socket prematurely if ApplicationContext is slow to start connector.setProperty("bindOnInit", "false"); if (getSsl() != null && getSsl().isEnabled()) { - TomcatConnectorCustomizer ssl = new SslConnectorCustomizer(getSsl(), getSslStoreProvider()); - ssl.customize(connector); - if (getHttp2() != null && getHttp2().getEnabled()) { - connector.addUpgradeProtocol(new Http2Protocol()); - } + customizeSsl(connector); } - TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression()); + TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer( + getCompression()); compression.customize(connector); for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) { customizer.customize(connector); @@ -162,6 +155,13 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac } } + private void customizeSsl(Connector connector) { + new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); + if (getHttp2() != null && getHttp2().getEnabled()) { + connector.addUpgradeProtocol(new Http2Protocol()); + } + } + /** * Set {@link TomcatContextCustomizer}s that should be applied to the Tomcat * {@link Context} . Calling this method will replace any existing customizers. @@ -260,7 +260,6 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac this.contextLifecycleListeners.addAll(Arrays.asList(contextLifecycleListeners)); } - /** * Factory method called to create the {@link TomcatWebServer}. Subclasses can * override this method to return a different {@link TomcatWebServer} or apply diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java index eb2ee922f7..2b34126bcd 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java @@ -111,7 +111,8 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto private List contextValves = new ArrayList<>(); - private List contextLifecycleListeners = Arrays.asList(new AprLifecycleListener()); + private List contextLifecycleListeners = new ArrayList<>( + Collections.singleton(new AprLifecycleListener())); private List tomcatContextCustomizers = new ArrayList<>(); @@ -293,19 +294,13 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto if (getUriEncoding() != null) { connector.setURIEncoding(getUriEncoding().name()); } - - // If ApplicationContext is slow to start we want Tomcat not to bind to the socket - // prematurely... + // Don't bind to the socket prematurely if ApplicationContext is slow to start connector.setProperty("bindOnInit", "false"); - if (getSsl() != null && getSsl().isEnabled()) { - TomcatConnectorCustomizer ssl = new SslConnectorCustomizer(getSsl(), getSslStoreProvider()); - ssl.customize(connector); - if (getHttp2() != null && getHttp2().getEnabled()) { - connector.addUpgradeProtocol(new Http2Protocol()); - } + customizeSsl(connector); } - TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression()); + TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer( + getCompression()); compression.customize(connector); for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) { customizer.customize(connector); @@ -318,6 +313,13 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto } } + private void customizeSsl(Connector connector) { + new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); + if (getHttp2() != null && getHttp2().getEnabled()) { + connector.addUpgradeProtocol(new Http2Protocol()); + } + } + /** * Configure the Tomcat {@link Context}. * @param context the Tomcat context diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java index 964389638e..218b97c026 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java @@ -44,8 +44,7 @@ import org.springframework.boot.web.server.SslStoreProvider; import org.springframework.util.ResourceUtils; /** - * {@link UndertowBuilderCustomizer} that configures SSL - * on the given builder instance. + * {@link UndertowBuilderCustomizer} that configures SSL on the given builder instance. * * @author Brian Clozel */ @@ -59,8 +58,8 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { private final SslStoreProvider sslStoreProvider; - SslBuilderCustomizer(int port, InetAddress address, - Ssl ssl, SslStoreProvider sslStoreProvider) { + SslBuilderCustomizer(int port, InetAddress address, Ssl ssl, + SslStoreProvider sslStoreProvider) { this.port = port; this.address = address; this.ssl = ssl; @@ -73,7 +72,8 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { SSLContext sslContext = SSLContext.getInstance(this.ssl.getProtocol()); sslContext.init(getKeyManagers(this.ssl, this.sslStoreProvider), getTrustManagers(this.ssl, this.sslStoreProvider), null); - builder.addHttpsListener(this.port, getListenAddress(this.address), sslContext); + builder.addHttpsListener(this.port, getListenAddress(this.address), + sslContext); builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, getSslClientAuthMode(this.ssl)); if (this.ssl.getEnabledProtocols() != null) { @@ -143,7 +143,8 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { return keyManagers; } - private KeyStore getKeyStore(Ssl ssl, SslStoreProvider sslStoreProvider) throws Exception { + private KeyStore getKeyStore(Ssl ssl, SslStoreProvider sslStoreProvider) + throws Exception { if (sslStoreProvider != null) { return sslStoreProvider.getKeyStore(); } @@ -164,7 +165,8 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { } } - private KeyStore getTrustStore(Ssl ssl, SslStoreProvider sslStoreProvider) throws Exception { + private KeyStore getTrustStore(Ssl ssl, SslStoreProvider sslStoreProvider) + throws Exception { if (sslStoreProvider != null) { return sslStoreProvider.getTrustStore(); } @@ -247,4 +249,5 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { } } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java index 49115d2a0e..ea5d64ce29 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java @@ -87,12 +87,7 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF builder.setDirectBuffers(this.directBuffers); } if (getSsl() != null && getSsl().isEnabled()) { - SslBuilderCustomizer sslBuilderCustomizer = - new SslBuilderCustomizer(getPort(), getAddress(), getSsl(), getSslStoreProvider()); - sslBuilderCustomizer.customize(builder); - if (getHttp2() != null) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, getHttp2().getEnabled()); - } + customizeSsl(builder); } else { builder.addHttpListener(port, getListenAddress()); @@ -103,6 +98,15 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF return builder; } + private void customizeSsl(Undertow.Builder builder) { + new SslBuilderCustomizer(getPort(), getAddress(), getSsl(), getSslStoreProvider()) + .customize(builder); + if (getHttp2() != null) { + builder.setServerOption(UndertowOptions.ENABLE_HTTP2, + getHttp2().getEnabled()); + } + } + private String getListenAddress() { if (getAddress() == null) { return "0.0.0.0"; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java index ce80dda3c0..f19ea53d76 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java @@ -233,12 +233,7 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac builder.setDirectBuffers(this.directBuffers); } if (getSsl() != null && getSsl().isEnabled()) { - SslBuilderCustomizer sslBuilderCustomizer = - new SslBuilderCustomizer(getPort(), getAddress(), getSsl(), getSslStoreProvider()); - sslBuilderCustomizer.customize(builder); - if (getHttp2() != null) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, getHttp2().getEnabled()); - } + customizeSsl(builder); } else { builder.addHttpListener(port, getListenAddress()); @@ -249,6 +244,15 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac return builder; } + private void customizeSsl(Builder builder) { + new SslBuilderCustomizer(getPort(), getAddress(), getSsl(), getSslStoreProvider()) + .customize(builder); + if (getHttp2() != null) { + builder.setServerOption(UndertowOptions.ENABLE_HTTP2, + getHttp2().getEnabled()); + } + } + private String getListenAddress() { if (getAddress() == null) { return "0.0.0.0"; @@ -602,7 +606,6 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac } } - private static final class LoaderHidingResourceManager implements ResourceManager { private final ResourceManager delegate; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java index eb3c0e75b5..b4687974c7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java @@ -36,4 +36,5 @@ public class Http2 { public void setEnabled(boolean enabled) { this.enabled = enabled; } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java index 655797f3f7..fb31a9a28d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java @@ -56,13 +56,11 @@ public class SslConnectorCustomizerTests { Ssl ssl = new Ssl(); ssl.setKeyStore("test.jks"); ssl.setKeyStorePassword("secret"); - ssl.setCiphers(new String[] {"ALPHA", "BRAVO", "CHARLIE"}); - + ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); SslConnectorCustomizer customizer = new SslConnectorCustomizer(ssl, null); Connector connector = this.tomcat.getConnector(); customizer.customize(connector); this.tomcat.start(); - SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler() .findSslHostConfigs(); assertThat(sslHostConfigs[0].getCiphers()).isEqualTo("ALPHA:BRAVO:CHARLIE"); @@ -73,15 +71,12 @@ public class SslConnectorCustomizerTests { Ssl ssl = new Ssl(); ssl.setKeyPassword("password"); ssl.setKeyStore("src/test/resources/test.jks"); - - ssl.setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); - ssl.setCiphers(new String[] {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO"}); - + ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); + ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); SslConnectorCustomizer customizer = new SslConnectorCustomizer(ssl, null); Connector connector = this.tomcat.getConnector(); customizer.customize(connector); this.tomcat.start(); - SSLHostConfig sslHostConfig = connector.getProtocolHandler() .findSslHostConfigs()[0]; assertThat(sslHostConfig.getSslProtocol()).isEqualTo("TLS"); @@ -94,18 +89,16 @@ public class SslConnectorCustomizerTests { Ssl ssl = new Ssl(); ssl.setKeyPassword("password"); ssl.setKeyStore("src/test/resources/test.jks"); - - ssl.setEnabledProtocols(new String[] {"TLSv1.2"}); - ssl.setCiphers(new String[] {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO"}); - + ssl.setEnabledProtocols(new String[] { "TLSv1.2" }); + ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); SslConnectorCustomizer customizer = new SslConnectorCustomizer(ssl, null); Connector connector = this.tomcat.getConnector(); customizer.customize(connector); this.tomcat.start(); - SSLHostConfig sslHostConfig = connector.getProtocolHandler() .findSslHostConfigs()[0]; assertThat(sslHostConfig.getSslProtocol()).isEqualTo("TLS"); assertThat(sslHostConfig.getEnabledProtocols()).containsExactly("TLSv1.2"); } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java index 25a3360784..2d03f690b0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java @@ -67,9 +67,8 @@ public class TomcatReactiveWebServerFactoryTests @Test public void defaultTomcatListeners() throws Exception { TomcatReactiveWebServerFactory factory = getFactory(); - assertThat(factory.getContextLifecycleListeners()) - .hasSize(1) - .first().isInstanceOf(AprLifecycleListener.class); + assertThat(factory.getContextLifecycleListeners()).hasSize(1).first() + .isInstanceOf(AprLifecycleListener.class); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java index 1fe22f331a..65e7b3832f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java @@ -104,9 +104,8 @@ public class TomcatServletWebServerFactoryTests @Test public void defaultTomcatListeners() throws Exception { TomcatServletWebServerFactory factory = getFactory(); - assertThat(factory.getContextLifecycleListeners()) - .hasSize(1) - .first().isInstanceOf(AprLifecycleListener.class); + assertThat(factory.getContextLifecycleListeners()).hasSize(1).first() + .isInstanceOf(AprLifecycleListener.class); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java index 55401eeeb1..777539e6be 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java @@ -39,11 +39,13 @@ public class SslBuilderCustomizerTests { Ssl ssl = new Ssl(); ssl.setKeyPassword("password"); ssl.setKeyStore("src/test/resources/test.jks"); - SslBuilderCustomizer customizer = new SslBuilderCustomizer(8080, InetAddress.getLocalHost(), ssl, null); + SslBuilderCustomizer customizer = new SslBuilderCustomizer(8080, + InetAddress.getLocalHost(), ssl, null); KeyManager[] keyManagers = ReflectionTestUtils.invokeMethod(customizer, "getKeyManagers", ssl, null); Class name = Class.forName("org.springframework.boot.web.embedded.undertow" + ".SslBuilderCustomizer$ConfigurableAliasKeyManager"); assertThat(keyManagers[0]).isNotInstanceOf(name); } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java index bd6b0e30ba..f62a2075f6 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java @@ -79,8 +79,8 @@ public abstract class AbstractReactiveWebServerFactoryTests { factory.setPort(specificPort); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); - Mono result = getWebClient().build().post() - .uri("/test").contentType(MediaType.TEXT_PLAIN) + Mono result = getWebClient().build().post().uri("/test") + .contentType(MediaType.TEXT_PLAIN) .body(BodyInserters.fromObject("Hello World")).exchange() .flatMap((response) -> response.bodyToMono(String.class)); assertThat(result.block()).isEqualTo("Hello World"); @@ -97,7 +97,6 @@ public abstract class AbstractReactiveWebServerFactoryTests { testBasicSslWithKeyStore("src/test/resources/test.jks"); } - protected final void testBasicSslWithKeyStore(String keyStore) throws Exception { AbstractReactiveWebServerFactory factory = getFactory(); Ssl ssl = new Ssl(); @@ -106,30 +105,27 @@ public abstract class AbstractReactiveWebServerFactoryTests { factory.setSsl(ssl); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); - ReactorClientHttpConnector connector = buildTrustAllSslConnector(); WebClient client = WebClient.builder() .baseUrl("https://localhost:" + this.webServer.getPort()) .clientConnector(connector).build(); - - Mono result = client.post() - .uri("/test").contentType(MediaType.TEXT_PLAIN) + Mono result = client.post().uri("/test").contentType(MediaType.TEXT_PLAIN) .body(BodyInserters.fromObject("Hello World")).exchange() .flatMap((response) -> response.bodyToMono(String.class)); assertThat(result.block()).isEqualTo("Hello World"); } protected ReactorClientHttpConnector buildTrustAllSslConnector() { - return new ReactorClientHttpConnector(options -> options - .sslSupport(sslContextBuilder -> { - sslContextBuilder - .sslProvider(SslProvider.JDK) + return new ReactorClientHttpConnector( + (options) -> options.sslSupport(sslContextBuilder -> { + sslContextBuilder.sslProvider(SslProvider.JDK) .trustManager(InsecureTrustManagerFactory.INSTANCE); })); } protected WebClient.Builder getWebClient() { - return WebClient.builder().baseUrl("http://localhost:" + this.webServer.getPort()); + return WebClient.builder() + .baseUrl("http://localhost:" + this.webServer.getPort()); } protected static class EchoHandler implements HttpHandler {