Commit 5a74f63f authored by Andy Wilkinson's avatar Andy Wilkinson

Polish "Configure ErrorReportValve not to report stack traces"

Closes gh-11790
parent 29736e34
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -38,7 +38,6 @@ import org.apache.catalina.connector.Connector; ...@@ -38,7 +38,6 @@ import org.apache.catalina.connector.Connector;
import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.ErrorReportValve;
import org.apache.catalina.valves.RemoteIpValve; import org.apache.catalina.valves.RemoteIpValve;
import org.apache.commons.logging.LogFactory;
import org.apache.coyote.AbstractProtocol; import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.ProtocolHandler; import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.coyote.http11.AbstractHttp11Protocol;
...@@ -861,26 +860,26 @@ public class ServerProperties ...@@ -861,26 +860,26 @@ public class ServerProperties
if (!ObjectUtils.isEmpty(this.additionalTldSkipPatterns)) { if (!ObjectUtils.isEmpty(this.additionalTldSkipPatterns)) {
factory.getTldSkipPatterns().addAll(this.additionalTldSkipPatterns); factory.getTldSkipPatterns().addAll(this.additionalTldSkipPatterns);
} }
if (serverProperties.getError().getIncludeStacktrace() == ErrorProperties.IncludeStacktrace.NEVER) { if (serverProperties.getError()
.getIncludeStacktrace() == ErrorProperties.IncludeStacktrace.NEVER) {
customizeErrorReportValve(factory);
}
}
private void customizeErrorReportValve(
TomcatEmbeddedServletContainerFactory factory) {
factory.addContextCustomizers(new TomcatContextCustomizer() { factory.addContextCustomizers(new TomcatContextCustomizer() {
@Override @Override
public void customize(Context context) { public void customize(Context context) {
// org.apache.catalina.core.StandardHost() adds ErrorReportValve
// with default options if not there yet, so adding a properly
// configured one.
ErrorReportValve valve = new ErrorReportValve(); ErrorReportValve valve = new ErrorReportValve();
valve.setShowServerInfo(false); // disable server name and version valve.setShowServerInfo(false);
valve.setShowReport(false); // disable exception valve.setShowReport(false);
if (context.getParent() != null) {
context.getParent().getPipeline().addValve(valve); context.getParent().getPipeline().addValve(valve);
} else {
LogFactory.getLog(context.getClass()).warn("Parent of " + context
+ " is not set, skip ErrorReportValve configuration");
}
} }
}); });
} }
}
private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) { private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) {
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
......
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -32,6 +32,7 @@ import javax.servlet.SessionTrackingMode; ...@@ -32,6 +32,7 @@ import javax.servlet.SessionTrackingMode;
import org.apache.catalina.Context; import org.apache.catalina.Context;
import org.apache.catalina.Valve; import org.apache.catalina.Valve;
import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.valves.ErrorReportValve;
import org.apache.catalina.valves.RemoteIpValve; import org.apache.catalina.valves.RemoteIpValve;
import org.apache.coyote.AbstractProtocol; import org.apache.coyote.AbstractProtocol;
import org.junit.Before; import org.junit.Before;
...@@ -45,7 +46,6 @@ import org.springframework.boot.bind.RelaxedDataBinder; ...@@ -45,7 +46,6 @@ import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
...@@ -235,6 +235,25 @@ public class ServerPropertiesTests { ...@@ -235,6 +235,25 @@ public class ServerPropertiesTests {
assertThat(tomcat.getBackgroundProcessorDelay()).isEqualTo(10); assertThat(tomcat.getBackgroundProcessorDelay()).isEqualTo(10);
} }
@Test
public void errorReportValveIsConfiguredToNotReportStackTraces() {
TomcatEmbeddedServletContainerFactory tomcatContainer = new TomcatEmbeddedServletContainerFactory();
Map<String, String> map = new HashMap<String, String>();
bindProperties(map);
this.properties.customize(tomcatContainer);
Valve[] valves = ((TomcatEmbeddedServletContainer) tomcatContainer
.getEmbeddedServletContainer()).getTomcat().getHost().getPipeline()
.getValves();
assertThat(valves).hasAtLeastOneElementOfType(ErrorReportValve.class);
for (Valve valve : valves) {
if (valve instanceof ErrorReportValve) {
ErrorReportValve errorReportValve = (ErrorReportValve) valve;
assertThat(errorReportValve.isShowReport()).isFalse();
assertThat(errorReportValve.isShowServerInfo()).isFalse();
}
}
}
@Test @Test
public void redirectContextRootIsNotConfiguredByDefault() throws Exception { public void redirectContextRootIsNotConfiguredByDefault() throws Exception {
bindProperties(new HashMap<String, String>()); bindProperties(new HashMap<String, String>());
...@@ -249,14 +268,10 @@ public class ServerPropertiesTests { ...@@ -249,14 +268,10 @@ public class ServerPropertiesTests {
bindProperties(map); bindProperties(map);
ServerProperties.Tomcat tomcat = this.properties.getTomcat(); ServerProperties.Tomcat tomcat = this.properties.getTomcat();
assertThat(tomcat.getRedirectContextRoot()).isEqualTo(false); assertThat(tomcat.getRedirectContextRoot()).isEqualTo(false);
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory(); TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
this.properties.customize(container); Context context = (Context) ((TomcatEmbeddedServletContainer) factory
Context context = mock(Context.class); .getEmbeddedServletContainer()).getTomcat().getHost().findChildren()[0];
for (TomcatContextCustomizer customizer : container assertThat(context.getMapperContextRootRedirectEnabled()).isTrue();
.getTomcatContextCustomizers()) {
customizer.customize(context);
}
verify(context).setMapperContextRootRedirectEnabled(false);
} }
@Test @Test
......
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
......
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -53,6 +53,8 @@ import org.junit.After; ...@@ -53,6 +53,8 @@ import org.junit.After;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.InOrder; import org.mockito.InOrder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests; import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
...@@ -68,6 +70,7 @@ import static org.junit.Assert.fail; ...@@ -68,6 +70,7 @@ import static org.junit.Assert.fail;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
...@@ -146,6 +149,25 @@ public class TomcatEmbeddedServletContainerFactoryTests ...@@ -146,6 +149,25 @@ public class TomcatEmbeddedServletContainerFactoryTests
} }
} }
@Test
public void contextIsAddedToHostBeforeCustomizersAreCalled() throws Exception {
TomcatEmbeddedServletContainerFactory factory = getFactory();
TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
assertThat(((Context) invocation.getArguments()[0]).getParent())
.isNotNull();
return null;
}
}).when(customizer).customize(any(Context.class));
factory.addContextCustomizers(customizer);
this.container = factory.getEmbeddedServletContainer();
verify(customizer).customize(any(Context.class));
}
@Test @Test
public void tomcatConnectorCustomizers() throws Exception { public void tomcatConnectorCustomizers() throws Exception {
TomcatEmbeddedServletContainerFactory factory = getFactory(); TomcatEmbeddedServletContainerFactory factory = getFactory();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment