Allow Tomcat context root redirect to be configured via the environment
This commit adds a new property, server.tomcat.redirect-context-root, that can be used to configure the Tomcat Context’s mapperContextRootRedirectEnabled property. The default is to not apply any configuration and, therefore, to use Tomcat’s default of true. Closes gh-6248
This commit is contained in:
parent
05b9dd1cb9
commit
2b970f9efc
|
@ -646,6 +646,12 @@ public class ServerProperties
|
|||
*/
|
||||
private int maxHttpHeaderSize = 0; // bytes
|
||||
|
||||
/**
|
||||
* Whether requests to the context root should be redirected by appending a / to
|
||||
* the path.
|
||||
*/
|
||||
private Boolean redirectContextRoot;
|
||||
|
||||
/**
|
||||
* Character encoding to use to decode the URI.
|
||||
*/
|
||||
|
@ -742,6 +748,14 @@ public class ServerProperties
|
|||
this.portHeader = portHeader;
|
||||
}
|
||||
|
||||
public Boolean getRedirectContextRoot() {
|
||||
return this.redirectContextRoot;
|
||||
}
|
||||
|
||||
public void setRedirectContextRoot(Boolean redirectContextRoot) {
|
||||
this.redirectContextRoot = redirectContextRoot;
|
||||
}
|
||||
|
||||
public String getRemoteIpHeader() {
|
||||
return this.remoteIpHeader;
|
||||
}
|
||||
|
@ -789,6 +803,9 @@ public class ServerProperties
|
|||
customizeConnectionTimeout(factory,
|
||||
serverProperties.getConnectionTimeout());
|
||||
}
|
||||
if (this.redirectContextRoot != null) {
|
||||
customizeRedirectContextRoot(factory, this.redirectContextRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private void customizeConnectionTimeout(
|
||||
|
@ -911,6 +928,19 @@ public class ServerProperties
|
|||
factory.addContextValves(valve);
|
||||
}
|
||||
|
||||
private void customizeRedirectContextRoot(
|
||||
TomcatEmbeddedServletContainerFactory factory,
|
||||
final boolean redirectContextRoot) {
|
||||
factory.addContextCustomizers(new TomcatContextCustomizer() {
|
||||
|
||||
@Override
|
||||
public void customize(Context context) {
|
||||
context.setMapperContextRootRedirectEnabled(redirectContextRoot);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static class Accesslog {
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.SessionCookieConfig;
|
||||
import javax.servlet.SessionTrackingMode;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Valve;
|
||||
import org.apache.catalina.valves.RemoteIpValve;
|
||||
import org.junit.Before;
|
||||
|
@ -41,6 +42,7 @@ import org.springframework.beans.MutablePropertyValues;
|
|||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
|
||||
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
|
@ -150,6 +152,30 @@ public class ServerPropertiesTests {
|
|||
.isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redirectContextRootIsNotConfiguredByDefault() throws Exception {
|
||||
bindProperties(new HashMap<String, String>());
|
||||
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
|
||||
assertThat(tomcat.getRedirectContextRoot()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redirectContextRootCanBeConfigured() throws Exception {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("server.tomcat.redirect-context-root", "false");
|
||||
bindProperties(map);
|
||||
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
|
||||
assertThat(tomcat.getRedirectContextRoot()).isEqualTo(false);
|
||||
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
|
||||
this.properties.customize(container);
|
||||
Context context = mock(Context.class);
|
||||
for (TomcatContextCustomizer customizer : container
|
||||
.getTomcatContextCustomizers()) {
|
||||
customizer.customize(context);
|
||||
}
|
||||
verify(context).setMapperContextRootRedirectEnabled(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrailingSlashOfContextPathIsRemoved() {
|
||||
new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues(
|
||||
|
|
|
@ -214,6 +214,7 @@ content into your application; rather pick only the properties that you need.
|
|||
server.tomcat.port-header=X-Forwarded-Port # Name of the HTTP header used to override the original port value.
|
||||
server.tomcat.protocol-header= # Header that holds the incoming protocol, usually named "X-Forwarded-Proto".
|
||||
server.tomcat.protocol-header-https-value=https # Value of the protocol header that indicates that the incoming request uses SSL.
|
||||
server.tomcat.redirect-context-root= # Whether requests to the context root should be redirected by appending a / to the path.
|
||||
server.tomcat.remote-ip-header= # Name of the http header from which the remote ip is extracted. For instance `X-FORWARDED-FOR`
|
||||
server.tomcat.uri-encoding=UTF-8 # Character encoding to use to decode the URI.
|
||||
server.undertow.accesslog.dir= # Undertow access log directory.
|
||||
|
|
|
@ -184,7 +184,6 @@ public class TomcatEmbeddedServletContainerFactory
|
|||
: ClassUtils.getDefaultClassLoader());
|
||||
try {
|
||||
context.setUseRelativeRedirects(false);
|
||||
context.setMapperContextRootRedirectEnabled(true);
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Tomcat is < 8.0.30. Continue
|
||||
|
|
Loading…
Reference in New Issue