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:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user