Skip to content

Commit 5a74f63

Browse files
committed
Polish "Configure ErrorReportValve not to report stack traces"
Closes gh-11790
1 parent 29736e3 commit 5a74f63

File tree

4 files changed

+68
-32
lines changed

4 files changed

+68
-32
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,7 +38,6 @@
3838
import org.apache.catalina.valves.AccessLogValve;
3939
import org.apache.catalina.valves.ErrorReportValve;
4040
import org.apache.catalina.valves.RemoteIpValve;
41-
import org.apache.commons.logging.LogFactory;
4241
import org.apache.coyote.AbstractProtocol;
4342
import org.apache.coyote.ProtocolHandler;
4443
import org.apache.coyote.http11.AbstractHttp11Protocol;
@@ -861,27 +860,27 @@ void customizeTomcat(ServerProperties serverProperties,
861860
if (!ObjectUtils.isEmpty(this.additionalTldSkipPatterns)) {
862861
factory.getTldSkipPatterns().addAll(this.additionalTldSkipPatterns);
863862
}
864-
if (serverProperties.getError().getIncludeStacktrace() == ErrorProperties.IncludeStacktrace.NEVER) {
865-
factory.addContextCustomizers(new TomcatContextCustomizer() {
866-
@Override
867-
public void customize(Context context) {
868-
// org.apache.catalina.core.StandardHost() adds ErrorReportValve
869-
// with default options if not there yet, so adding a properly
870-
// configured one.
871-
ErrorReportValve valve = new ErrorReportValve();
872-
valve.setShowServerInfo(false); // disable server name and version
873-
valve.setShowReport(false); // disable exception
874-
if (context.getParent() != null) {
875-
context.getParent().getPipeline().addValve(valve);
876-
} else {
877-
LogFactory.getLog(context.getClass()).warn("Parent of " + context
878-
+ " is not set, skip ErrorReportValve configuration");
879-
}
880-
}
881-
});
863+
if (serverProperties.getError()
864+
.getIncludeStacktrace() == ErrorProperties.IncludeStacktrace.NEVER) {
865+
customizeErrorReportValve(factory);
882866
}
883867
}
884868

869+
private void customizeErrorReportValve(
870+
TomcatEmbeddedServletContainerFactory factory) {
871+
factory.addContextCustomizers(new TomcatContextCustomizer() {
872+
873+
@Override
874+
public void customize(Context context) {
875+
ErrorReportValve valve = new ErrorReportValve();
876+
valve.setShowServerInfo(false);
877+
valve.setShowReport(false);
878+
context.getParent().getPipeline().addValve(valve);
879+
}
880+
881+
});
882+
}
883+
885884
private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) {
886885
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
887886

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
3232
import org.apache.catalina.Context;
3333
import org.apache.catalina.Valve;
3434
import org.apache.catalina.valves.AccessLogValve;
35+
import org.apache.catalina.valves.ErrorReportValve;
3536
import org.apache.catalina.valves.RemoteIpValve;
3637
import org.apache.coyote.AbstractProtocol;
3738
import org.junit.Before;
@@ -45,7 +46,6 @@
4546
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
4647
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
4748
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
48-
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
4949
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
5050
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
5151
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
@@ -235,6 +235,25 @@ public void testTomcatBinding() throws Exception {
235235
assertThat(tomcat.getBackgroundProcessorDelay()).isEqualTo(10);
236236
}
237237

238+
@Test
239+
public void errorReportValveIsConfiguredToNotReportStackTraces() {
240+
TomcatEmbeddedServletContainerFactory tomcatContainer = new TomcatEmbeddedServletContainerFactory();
241+
Map<String, String> map = new HashMap<String, String>();
242+
bindProperties(map);
243+
this.properties.customize(tomcatContainer);
244+
Valve[] valves = ((TomcatEmbeddedServletContainer) tomcatContainer
245+
.getEmbeddedServletContainer()).getTomcat().getHost().getPipeline()
246+
.getValves();
247+
assertThat(valves).hasAtLeastOneElementOfType(ErrorReportValve.class);
248+
for (Valve valve : valves) {
249+
if (valve instanceof ErrorReportValve) {
250+
ErrorReportValve errorReportValve = (ErrorReportValve) valve;
251+
assertThat(errorReportValve.isShowReport()).isFalse();
252+
assertThat(errorReportValve.isShowServerInfo()).isFalse();
253+
}
254+
}
255+
}
256+
238257
@Test
239258
public void redirectContextRootIsNotConfiguredByDefault() throws Exception {
240259
bindProperties(new HashMap<String, String>());
@@ -249,14 +268,10 @@ public void redirectContextRootCanBeConfigured() throws Exception {
249268
bindProperties(map);
250269
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
251270
assertThat(tomcat.getRedirectContextRoot()).isEqualTo(false);
252-
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
253-
this.properties.customize(container);
254-
Context context = mock(Context.class);
255-
for (TomcatContextCustomizer customizer : container
256-
.getTomcatContextCustomizers()) {
257-
customizer.customize(context);
258-
}
259-
verify(context).setMapperContextRootRedirectEnabled(false);
271+
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
272+
Context context = (Context) ((TomcatEmbeddedServletContainer) factory
273+
.getEmbeddedServletContainer()).getTomcat().getHost().findChildren()[0];
274+
assertThat(context.getMapperContextRootRedirectEnabled()).isTrue();
260275
}
261276

262277
@Test

spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,6 +53,8 @@
5353
import org.junit.Rule;
5454
import org.junit.Test;
5555
import org.mockito.InOrder;
56+
import org.mockito.invocation.InvocationOnMock;
57+
import org.mockito.stubbing.Answer;
5658

5759
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
5860
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
@@ -68,6 +70,7 @@
6870
import static org.mockito.BDDMockito.given;
6971
import static org.mockito.Matchers.any;
7072
import static org.mockito.Matchers.anyObject;
73+
import static org.mockito.Mockito.doAnswer;
7174
import static org.mockito.Mockito.inOrder;
7275
import static org.mockito.Mockito.mock;
7376
import static org.mockito.Mockito.verify;
@@ -146,6 +149,25 @@ public void tomcatCustomizers() throws Exception {
146149
}
147150
}
148151

152+
@Test
153+
public void contextIsAddedToHostBeforeCustomizersAreCalled() throws Exception {
154+
TomcatEmbeddedServletContainerFactory factory = getFactory();
155+
TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class);
156+
doAnswer(new Answer<Void>() {
157+
158+
@Override
159+
public Void answer(InvocationOnMock invocation) throws Throwable {
160+
assertThat(((Context) invocation.getArguments()[0]).getParent())
161+
.isNotNull();
162+
return null;
163+
}
164+
165+
}).when(customizer).customize(any(Context.class));
166+
factory.addContextCustomizers(customizer);
167+
this.container = factory.getEmbeddedServletContainer();
168+
verify(customizer).customize(any(Context.class));
169+
}
170+
149171
@Test
150172
public void tomcatConnectorCustomizers() throws Exception {
151173
TomcatEmbeddedServletContainerFactory factory = getFactory();

0 commit comments

Comments
 (0)