From d9048d2531a261fbdf256276103d4fd74a14a81d Mon Sep 17 00:00:00 2001 From: HaiTao Zhang Date: Tue, 25 Jun 2019 13:39:39 -0700 Subject: [PATCH] Provide ability to add additional connectors on reactive Tomcat See gh-17323 --- .../TomcatReactiveWebServerFactory.java | 23 +++++++++++++++++++ .../TomcatReactiveWebServerFactoryTests.java | 20 ++++++++++++++++ 2 files changed, 43 insertions(+) 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 db6ac05e24..2932474b52 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 @@ -78,6 +78,8 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac private Collection> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(); + private final List additionalTomcatConnectors = new ArrayList<>(); + private String protocol = DEFAULT_PROTOCOL; private Charset uriEncoding = DEFAULT_CHARSET; @@ -122,6 +124,9 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); configureEngine(tomcat.getEngine()); + for (Connector additionalConnector : this.additionalTomcatConnectors) { + tomcat.getService().addConnector(additionalConnector); + } TomcatHttpHandlerAdapter servlet = new TomcatHttpHandlerAdapter(httpHandler); prepareContext(tomcat.getHost(), servlet); return new TomcatWebServer(tomcat, getPort() >= 0); @@ -317,6 +322,24 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac return this.tomcatProtocolHandlerCustomizers; } + /** + * Add {@link Connector}s in addition to the default connector, e.g. for SSL or AJP + * @param connectors the connectors to add + */ + public void addAdditionalTomcatConnectors(Connector... connectors) { + Assert.notNull(connectors, "Connectors must not be null"); + this.additionalTomcatConnectors.addAll(Arrays.asList(connectors)); + } + + /** + * Returns a mutable collection of the {@link Connector}s that will be added to the + * Tomcat. + * @return the additionalTomcatConnectors + */ + public List getAdditionalTomcatConnectors() { + return this.additionalTomcatConnectors; + } + @Override public void addEngineValves(Valve... engineValves) { Assert.notNull(engineValves, "Valves must not be null"); 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 348580b685..84a04166be 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 @@ -20,10 +20,12 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.util.Arrays; +import java.util.Map; import org.apache.catalina.Context; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; +import org.apache.catalina.Service; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.AprLifecycleListener; import org.apache.catalina.core.StandardContext; @@ -175,6 +177,24 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } } + @Test + void tomcatAdditionalConnectors() { + TomcatReactiveWebServerFactory factory = getFactory(); + Connector[] connectors = new Connector[4]; + Arrays.setAll(connectors, (i) -> new Connector()); + factory.addAdditionalTomcatConnectors(connectors); + this.webServer = factory.getWebServer(mock(HttpHandler.class)); + Map connectorsByService = ((TomcatWebServer) this.webServer).getServiceConnectors(); + assertThat(connectorsByService.values().iterator().next().length).isEqualTo(connectors.length + 1); + } + + @Test + void addNullAdditionalConnectorsThrows() { + TomcatReactiveWebServerFactory factory = getFactory(); + assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalTomcatConnectors((Connector[]) null)) + .withMessageContaining("Connectors must not be null"); + } + @Test void useForwardedHeaders() { TomcatReactiveWebServerFactory factory = getFactory();