Configure Undertow to eagerly initialize Filters by default

Closes gh-9232
pull/6224/merge
Andy Wilkinson 8 years ago
parent 6acf789264
commit d4140d6a69

@ -1129,6 +1129,11 @@ public class ServerProperties {
*/ */
private Boolean directBuffers; private Boolean directBuffers;
/**
* Whether servlet filters should be initialized on startup.
*/
private boolean eagerFilterInit = true;
private final Accesslog accesslog = new Accesslog(); private final Accesslog accesslog = new Accesslog();
public long getMaxHttpPostSize() { public long getMaxHttpPostSize() {
@ -1171,6 +1176,14 @@ public class ServerProperties {
this.directBuffers = directBuffers; this.directBuffers = directBuffers;
} }
public boolean isEagerFilterInit() {
return this.eagerFilterInit;
}
public void setEagerFilterInit(boolean eagerFilterInit) {
this.eagerFilterInit = eagerFilterInit;
}
public Accesslog getAccesslog() { public Accesslog getAccesslog() {
return this.accesslog; return this.accesslog;
} }

@ -472,11 +472,12 @@ public class DefaultServletWebServerFactoryCustomizer
customizeMaxHttpPostSize(factory, customizeMaxHttpPostSize(factory,
undertowProperties.getMaxHttpPostSize()); undertowProperties.getMaxHttpPostSize());
} }
if (serverProperties.getConnectionTimeout() != null) { if (serverProperties.getConnectionTimeout() != null) {
customizeConnectionTimeout(factory, customizeConnectionTimeout(factory,
serverProperties.getConnectionTimeout()); serverProperties.getConnectionTimeout());
} }
factory.addDeploymentInfoCustomizers((deploymentInfo) -> deploymentInfo
.setEagerFilterInit(undertowProperties.isEagerFilterInit()));
} }
private static void customizeConnectionTimeout( private static void customizeConnectionTimeout(

@ -246,6 +246,7 @@ content into your application; rather pick only the properties that you need.
server.undertow.buffer-size= # Size of each buffer in bytes. server.undertow.buffer-size= # Size of each buffer in bytes.
server.undertow.direct-buffers= # Allocate buffers outside the Java heap. server.undertow.direct-buffers= # Allocate buffers outside the Java heap.
server.undertow.io-threads= # Number of I/O threads to create for the worker. server.undertow.io-threads= # Number of I/O threads to create for the worker.
server.undertow.eager-filter-init=true # Whether servlet filters should be initialized on startup.
server.undertow.max-http-post-size=0 # Maximum size in bytes of the HTTP post content. server.undertow.max-http-post-size=0 # Maximum size in bytes of the HTTP post content.
server.undertow.worker-threads= # Number of worker threads. server.undertow.worker-threads= # Number of worker threads.

@ -137,6 +137,8 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
private boolean useForwardHeaders; private boolean useForwardHeaders;
private boolean eagerInitFilters = true;
/** /**
* Create a new {@link UndertowServletWebServerFactory} instance. * Create a new {@link UndertowServletWebServerFactory} instance.
*/ */
@ -392,6 +394,7 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
configureErrorPages(deployment); configureErrorPages(deployment);
deployment.setServletStackTraces(ServletStackTraces.NONE); deployment.setServletStackTraces(ServletStackTraces.NONE);
deployment.setResourceManager(getDocumentRootResourceManager()); deployment.setResourceManager(getDocumentRootResourceManager());
deployment.setEagerFilterInit(this.eagerInitFilters);
configureMimeMappings(deployment); configureMimeMappings(deployment);
for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) { for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) {
customizer.customize(deployment); customizer.customize(deployment);
@ -637,6 +640,25 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
this.useForwardHeaders = useForwardHeaders; this.useForwardHeaders = useForwardHeaders;
} }
/**
* Return if filters should be initialized eagerly.
* @return {@code true} if filters are initialized eagerly, otherwise {@code false}.
* @since 2.0.0
*/
public boolean isEagerInitFilters() {
return this.eagerInitFilters;
}
/**
* Set whether filters should be initialized eagerly.
* @param eagerInitFilters {@code true} if filters are initialized eagerly, otherwise
* {@code false}.
* @since 2.0.0
*/
public void setEagerInitFilters(boolean eagerInitFilters) {
this.eagerInitFilters = eagerInitFilters;
}
/** /**
* {@link ResourceManager} that exposes resource in {@code META-INF/resources} * {@link ResourceManager} that exposes resource in {@code META-INF/resources}
* directory of nested (in {@code BOOT-INF/lib} or {@code WEB-INF/lib}) jars. * directory of nested (in {@code BOOT-INF/lib} or {@code WEB-INF/lib}) jars.

@ -23,13 +23,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -51,8 +45,6 @@ import org.mockito.InOrder;
import org.springframework.boot.web.server.Compression; import org.springframework.boot.web.server.Compression;
import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.PortInUseException;
import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
@ -285,38 +277,6 @@ public class JettyServletWebServerFactoryTests
.isSameAs(threadPool); .isSameAs(threadPool);
} }
@Test
public void faultyFilterCausesStartFailure() throws Exception {
JettyServletWebServerFactory factory = getFactory();
factory.addInitializers(new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addFilter("faulty", new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
throw new ServletException("Faulty filter");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
});
}
});
this.thrown.expect(WebServerException.class);
factory.getWebServer().start();
}
@Override @Override
@SuppressWarnings("serial") @SuppressWarnings("serial")
// Workaround for Jetty issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=470646 // Workaround for Jetty issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=470646

@ -26,13 +26,7 @@ import java.util.concurrent.TimeUnit;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.catalina.Container; import org.apache.catalina.Container;
import org.apache.catalina.Context; import org.apache.catalina.Context;
@ -57,7 +51,6 @@ import org.mockito.InOrder;
import org.springframework.boot.testutil.InternalOutputCapture; import org.springframework.boot.testutil.InternalOutputCapture;
import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.WebServerException; import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
@ -451,38 +444,6 @@ public class TomcatServletWebServerFactoryTests
assertThat(sessionIdGenerator.getJvmRoute()).isEqualTo("test"); assertThat(sessionIdGenerator.getJvmRoute()).isEqualTo("test");
} }
@Test
public void faultyFilterCausesStartFailure() throws Exception {
TomcatServletWebServerFactory factory = getFactory();
factory.addInitializers(new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addFilter("faulty", new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
throw new ServletException("Faulty filter");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
});
}
});
this.thrown.expect(WebServerException.class);
factory.getWebServer().start();
}
@Override @Override
protected JspServlet getJspServlet() throws ServletException { protected JspServlet getJspServlet() throws ServletException {
Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat(); Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat();

@ -50,6 +50,9 @@ import java.util.zip.GZIPInputStream;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.GenericServlet; import javax.servlet.GenericServlet;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -88,6 +91,7 @@ import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.server.Ssl.ClientAuth;
import org.springframework.boot.web.server.SslStoreProvider; import org.springframework.boot.web.server.SslStoreProvider;
import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
@ -944,6 +948,38 @@ public abstract class AbstractServletWebServerFactoryTests {
assertThat(options.getDevelopment()).isEqualTo(false); assertThat(options.getDevelopment()).isEqualTo(false);
} }
@Test
public void faultyFilterCausesStartFailure() throws Exception {
AbstractServletWebServerFactory factory = getFactory();
factory.addInitializers(new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addFilter("faulty", new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
throw new ServletException("Faulty filter");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
});
}
});
this.thrown.expect(WebServerException.class);
factory.getWebServer().start();
}
protected abstract void addConnector(int port, protected abstract void addConnector(int port,
AbstractServletWebServerFactory factory); AbstractServletWebServerFactory factory);

Loading…
Cancel
Save