This commit is contained in:
Phillip Webb
2017-11-03 13:35:07 -07:00
parent a0580da8fb
commit 427d262297
19 changed files with 140 additions and 140 deletions

View File

@@ -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);
}
}

View File

@@ -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.

View File

@@ -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 <<howto-configure-ssl, configure SSL first>>.
Spring Boot does not support `h2c`, the cleartext version of the HTTP/2 protocol. So you
must configure <<howto-configure-ssl, configure SSL first>>.
====
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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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());
}
}
}

View File

@@ -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()));
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -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<LifecycleListener> contextLifecycleListeners = Arrays.asList(new AprLifecycleListener());
private List<LifecycleListener> contextLifecycleListeners = new ArrayList<LifecycleListener>(
Collections.singleton(new AprLifecycleListener()));
private List<TomcatContextCustomizer> 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

View File

@@ -111,7 +111,8 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
private List<Valve> contextValves = new ArrayList<>();
private List<LifecycleListener> contextLifecycleListeners = Arrays.asList(new AprLifecycleListener());
private List<LifecycleListener> contextLifecycleListeners = new ArrayList<>(
Collections.singleton(new AprLifecycleListener()));
private List<TomcatContextCustomizer> 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

View File

@@ -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 {
}
}
}

View File

@@ -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";

View File

@@ -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;

View File

@@ -36,4 +36,5 @@ public class Http2 {
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -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");
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -79,8 +79,8 @@ public abstract class AbstractReactiveWebServerFactoryTests {
factory.setPort(specificPort);
this.webServer = factory.getWebServer(new EchoHandler());
this.webServer.start();
Mono<String> result = getWebClient().build().post()
.uri("/test").contentType(MediaType.TEXT_PLAIN)
Mono<String> 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<String> result = client.post()
.uri("/test").contentType(MediaType.TEXT_PLAIN)
Mono<String> 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 {