Merge branch '1.5.x'
This commit is contained in:
commit
244a287484
|
|
@ -20,11 +20,14 @@ import java.time.Duration;
|
||||||
|
|
||||||
import org.apache.catalina.Lifecycle;
|
import org.apache.catalina.Lifecycle;
|
||||||
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.apache.coyote.ProtocolHandler;
|
import org.apache.coyote.ProtocolHandler;
|
||||||
import org.apache.coyote.http11.AbstractHttp11Protocol;
|
import org.apache.coyote.http11.AbstractHttp11Protocol;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.web.ErrorProperties;
|
||||||
|
import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeStacktrace;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.cloud.CloudPlatform;
|
import org.springframework.boot.cloud.CloudPlatform;
|
||||||
import org.springframework.boot.context.properties.PropertyMapper;
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
|
|
@ -88,6 +91,7 @@ public final class TomcatCustomizer {
|
||||||
.when(TomcatCustomizer::isPositive)
|
.when(TomcatCustomizer::isPositive)
|
||||||
.to((acceptCount) -> customizeAcceptCount(factory, acceptCount));
|
.to((acceptCount) -> customizeAcceptCount(factory, acceptCount));
|
||||||
customizeStaticResources(serverProperties.getTomcat().getResource(), factory);
|
customizeStaticResources(serverProperties.getTomcat().getResource(), factory);
|
||||||
|
customizeErrorReportValve(serverProperties.getError(), factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPositive(int value) {
|
private static boolean isPositive(int value) {
|
||||||
|
|
@ -241,4 +245,16 @@ public final class TomcatCustomizer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void customizeErrorReportValve(ErrorProperties error,
|
||||||
|
ConfigurableTomcatWebServerFactory factory) {
|
||||||
|
if (error.getIncludeStacktrace() == IncludeStacktrace.NEVER) {
|
||||||
|
factory.addContextCustomizers((context) -> {
|
||||||
|
ErrorReportValve valve = new ErrorReportValve();
|
||||||
|
valve.setShowServerInfo(false);
|
||||||
|
valve.setShowReport(false);
|
||||||
|
context.getParent().getPipeline().addValve(valve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import org.apache.catalina.Context;
|
||||||
import org.apache.catalina.Valve;
|
import org.apache.catalina.Valve;
|
||||||
import org.apache.catalina.startup.Tomcat;
|
import org.apache.catalina.startup.Tomcat;
|
||||||
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.eclipse.jetty.server.NCSARequestLog;
|
import org.eclipse.jetty.server.NCSARequestLog;
|
||||||
|
|
@ -371,6 +372,24 @@ public class DefaultReactiveWebServerFactoryCustomizerTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void errorReportValveIsConfiguredToNotReportStackTraces() {
|
||||||
|
TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory();
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
bindProperties(map);
|
||||||
|
this.customizer.customize(factory);
|
||||||
|
Valve[] valves = ((TomcatWebServer) factory.getWebServer(mock(HttpHandler.class)))
|
||||||
|
.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 defaultUseForwardHeadersJetty() {
|
public void defaultUseForwardHeadersJetty() {
|
||||||
JettyReactiveWebServerFactory factory = spy(new JettyReactiveWebServerFactory());
|
JettyReactiveWebServerFactory factory = spy(new JettyReactiveWebServerFactory());
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import org.apache.catalina.Context;
|
||||||
import org.apache.catalina.Valve;
|
import org.apache.catalina.Valve;
|
||||||
import org.apache.catalina.startup.Tomcat;
|
import org.apache.catalina.startup.Tomcat;
|
||||||
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.eclipse.jetty.server.NCSARequestLog;
|
import org.eclipse.jetty.server.NCSARequestLog;
|
||||||
|
|
@ -182,6 +183,24 @@ public class DefaultServletWebServerFactoryCustomizerTests {
|
||||||
verify(context).setUseRelativeRedirects(true);
|
verify(context).setUseRelativeRedirects(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void errorReportValveIsConfiguredToNotReportStackTraces() {
|
||||||
|
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
bindProperties(map);
|
||||||
|
this.customizer.customize(factory);
|
||||||
|
Valve[] valves = ((TomcatWebServer) factory.getWebServer()).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 testCustomizeTomcat() {
|
public void testCustomizeTomcat() {
|
||||||
ConfigurableServletWebServerFactory factory = mock(
|
ConfigurableServletWebServerFactory factory = mock(
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,8 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
|
||||||
context.setLoader(loader);
|
context.setLoader(loader);
|
||||||
Tomcat.addServlet(context, "httpHandlerServlet", servlet);
|
Tomcat.addServlet(context, "httpHandlerServlet", servlet);
|
||||||
context.addServletMappingDecoded("/", "httpHandlerServlet");
|
context.addServletMappingDecoded("/", "httpHandlerServlet");
|
||||||
configureContext(context);
|
|
||||||
host.addChild(context);
|
host.addChild(context);
|
||||||
|
configureContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipAllTldScanning(TomcatEmbeddedContext context) {
|
private void skipAllTldScanning(TomcatEmbeddedContext context) {
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,8 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
|
||||||
}
|
}
|
||||||
context.addLifecycleListener(new StaticResourceConfigurer(context));
|
context.addLifecycleListener(new StaticResourceConfigurer(context));
|
||||||
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
|
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
|
||||||
configureContext(context, initializersToUse);
|
|
||||||
host.addChild(context);
|
host.addChild(context);
|
||||||
|
configureContext(context, initializersToUse);
|
||||||
postProcessContext(context);
|
postProcessContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
|
|
@ -25,14 +25,18 @@ import org.apache.catalina.connector.Connector;
|
||||||
import org.apache.catalina.core.AprLifecycleListener;
|
import org.apache.catalina.core.AprLifecycleListener;
|
||||||
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.web.reactive.server.AbstractReactiveWebServerFactoryTests;
|
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests;
|
||||||
import org.springframework.http.server.reactive.HttpHandler;
|
import org.springframework.http.server.reactive.HttpHandler;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link TomcatReactiveWebServerFactory}.
|
* Tests for {@link TomcatReactiveWebServerFactory}.
|
||||||
|
|
@ -64,6 +68,25 @@ public class TomcatReactiveWebServerFactoryTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextIsAddedToHostBeforeCustomizersAreCalled() throws Exception {
|
||||||
|
TomcatReactiveWebServerFactory 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.webServer = factory.getWebServer(mock(HttpHandler.class));
|
||||||
|
verify(customizer).customize(any(Context.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultTomcatListeners() {
|
public void defaultTomcatListeners() {
|
||||||
TomcatReactiveWebServerFactory factory = getFactory();
|
TomcatReactiveWebServerFactory factory = getFactory();
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,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.testsupport.rule.OutputCapture;
|
import org.springframework.boot.testsupport.rule.OutputCapture;
|
||||||
import org.springframework.boot.web.server.WebServerException;
|
import org.springframework.boot.web.server.WebServerException;
|
||||||
|
|
@ -61,6 +63,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
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;
|
||||||
|
|
@ -143,6 +146,25 @@ public class TomcatServletWebServerFactoryTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextIsAddedToHostBeforeCustomizersAreCalled() throws Exception {
|
||||||
|
TomcatServletWebServerFactory 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.webServer = factory.getWebServer();
|
||||||
|
verify(customizer).customize(any(Context.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tomcatConnectorCustomizers() {
|
public void tomcatConnectorCustomizers() {
|
||||||
TomcatServletWebServerFactory factory = getFactory();
|
TomcatServletWebServerFactory factory = getFactory();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue