Browse Source

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
pull/5879/merge
Andy Wilkinson 10 years ago
parent
commit
2b970f9efc
  1. 30
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
  2. 26
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java
  3. 1
      spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
  4. 1
      spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

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

@ -646,6 +646,12 @@ public class ServerProperties @@ -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 @@ -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 @@ -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 @@ -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 {
/**

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

@ -29,6 +29,7 @@ import javax.servlet.ServletException; @@ -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; @@ -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 { @@ -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(

1
spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc

@ -214,6 +214,7 @@ content into your application; rather pick only the properties that you need. @@ -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.

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

@ -184,7 +184,6 @@ public class TomcatEmbeddedServletContainerFactory @@ -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…
Cancel
Save