From 3009e5146c5d4ab549a7402f0d3a9f30e9c2ca64 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 20 Jun 2016 15:10:49 +0100 Subject: [PATCH] Disable Jetty's default Server header Following the upgrade to Tomcat 8.5, Jetty became the only container that sends a Server header by default. This commit updates the factory for Jetty to disable the default Server header bringing it into line with Tomcat and Undertow. All three containers continue to support server.server-header which can be used to configure a custom server header. Closes gh-4730 --- .../JettyEmbeddedServletContainerFactory.java | 19 +++++++++++++++++-- ...tEmbeddedServletContainerFactoryTests.java | 10 ++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index 7a670dc220..a80e3e22d6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -891,6 +891,13 @@ public class JettyEmbeddedServletContainerFactory ServerConnector connector = new ServerConnector(server, acceptors, selectors); connector.setHost(address.getHostName()); connector.setPort(address.getPort()); + for (ConnectionFactory connectionFactory : connector + .getConnectionFactories()) { + if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) { + ((HttpConfiguration.ConnectionFactory) connectionFactory) + .getHttpConfiguration().setSendServerVersion(false); + } + } return connector; } @@ -912,8 +919,16 @@ public class JettyEmbeddedServletContainerFactory .findMethod(Server.class, "setThreadPool", ThreadPool.class) .invoke(server, threadPool); } - catch (Exception e) { - throw new RuntimeException("Failed to configure Jetty 8 ThreadPool", e); + catch (Exception ex) { + throw new RuntimeException("Failed to configure Jetty 8 ThreadPool", ex); + } + try { + ReflectionUtils + .findMethod(Server.class, "setSendServerVersion", boolean.class) + .invoke(server, false); + } + catch (Exception ex) { + throw new RuntimeException("Failed to disable Server header", ex); } return server; } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index f9cd1df718..c275d9663f 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -813,6 +813,16 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { assertThat(response.getHeaders().getFirst("server")).isEqualTo("MyServer"); } + @Test + public void serverHeaderIsDisabledByDefault() throws Exception { + AbstractEmbeddedServletContainerFactory factory = getFactory(); + this.container = factory + .getEmbeddedServletContainer(exampleServletRegistration()); + this.container.start(); + ClientHttpResponse response = getClientResponse(getLocalUrl("/hello")); + assertThat(response.getHeaders().getFirst("server")).isNull(); + } + @Test public void portClashOfPrimaryConnectorResultsInPortInUseException() throws IOException {