Polish "Add support for configuring Tomcat's relaxed path and query chars"
See gh-17510
This commit is contained in:
@@ -396,6 +396,18 @@ public class ServerProperties {
|
||||
*/
|
||||
private List<String> additionalTldSkipPatterns = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Comma-separated list of additional unencoded characters that should be allowed
|
||||
* in URI paths. Only "< > [ \ ] ^ ` { | }" are allowed.
|
||||
*/
|
||||
private List<Character> relaxedPathChars = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Comma-separated list of additional unencoded characters that should be allowed
|
||||
* in URI query strings. Only "< > [ \ ] ^ ` { | }" are allowed.
|
||||
*/
|
||||
private List<Character> relaxedQueryChars = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Static resource configuration.
|
||||
*/
|
||||
@@ -406,20 +418,6 @@ public class ServerProperties {
|
||||
*/
|
||||
private final Mbeanregistry mbeanregistry = new Mbeanregistry();
|
||||
|
||||
/**
|
||||
* Specify additional unencoded characters that Tomcat should allow in a
|
||||
* querystring. The value may be any combination of the following characters: " <
|
||||
* > [ \ ] ^ ` { | } . Any other characters present in the value will be ignored.
|
||||
*/
|
||||
private String relaxedQueryChars;
|
||||
|
||||
/**
|
||||
* Specify additional unencoded characters that Tomcat should allow in the path.
|
||||
* The value may be any combination of the following characters: " < > [ \ ] ^ ` {
|
||||
* | } . Any other characters present in the value will be ignored.
|
||||
*/
|
||||
private String relaxedPathChars;
|
||||
|
||||
public int getMaxThreads() {
|
||||
return this.maxThreads;
|
||||
}
|
||||
@@ -568,6 +566,22 @@ public class ServerProperties {
|
||||
this.additionalTldSkipPatterns = additionalTldSkipPatterns;
|
||||
}
|
||||
|
||||
public List<Character> getRelaxedPathChars() {
|
||||
return this.relaxedPathChars;
|
||||
}
|
||||
|
||||
public void setRelaxedPathChars(List<Character> relaxedPathChars) {
|
||||
this.relaxedPathChars = relaxedPathChars;
|
||||
}
|
||||
|
||||
public List<Character> getRelaxedQueryChars() {
|
||||
return this.relaxedQueryChars;
|
||||
}
|
||||
|
||||
public void setRelaxedQueryChars(List<Character> relaxedQueryChars) {
|
||||
this.relaxedQueryChars = relaxedQueryChars;
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
@@ -576,22 +590,6 @@ public class ServerProperties {
|
||||
return this.mbeanregistry;
|
||||
}
|
||||
|
||||
public String getRelaxedPathChars() {
|
||||
return this.relaxedPathChars;
|
||||
}
|
||||
|
||||
public void setRelaxedPathChars(String relaxedPathChars) {
|
||||
this.relaxedPathChars = relaxedPathChars;
|
||||
}
|
||||
|
||||
public String getRelaxedQueryChars() {
|
||||
return this.relaxedQueryChars;
|
||||
}
|
||||
|
||||
public void setRelaxedQueryChars(String relaxedQueryChars) {
|
||||
this.relaxedQueryChars = relaxedQueryChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tomcat access log properties.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.catalina.Lifecycle;
|
||||
import org.apache.catalina.valves.AccessLogValve;
|
||||
@@ -103,10 +105,10 @@ public class TomcatWebServerFactoryCustomizer
|
||||
.to((acceptCount) -> customizeAcceptCount(factory, acceptCount));
|
||||
propertyMapper.from(tomcatProperties::getProcessorCache)
|
||||
.to((processorCache) -> customizeProcessorCache(factory, processorCache));
|
||||
propertyMapper.from(tomcatProperties::getRelaxedQueryChars)
|
||||
.to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars));
|
||||
propertyMapper.from(tomcatProperties::getRelaxedPathChars)
|
||||
propertyMapper.from(tomcatProperties::getRelaxedPathChars).as(this::joinCharacters).whenHasText()
|
||||
.to((relaxedChars) -> customizeRelaxedPathChars(factory, relaxedChars));
|
||||
propertyMapper.from(tomcatProperties::getRelaxedQueryChars).as(this::joinCharacters).whenHasText()
|
||||
.to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars));
|
||||
customizeStaticResources(factory);
|
||||
customizeErrorReportValve(properties.getError(), factory);
|
||||
}
|
||||
@@ -154,12 +156,16 @@ public class TomcatWebServerFactoryCustomizer
|
||||
});
|
||||
}
|
||||
|
||||
private void customizeRelaxedPathChars(ConfigurableTomcatWebServerFactory factory, String relaxedChars) {
|
||||
factory.addConnectorCustomizers((connector) -> connector.setAttribute("relaxedPathChars", relaxedChars));
|
||||
}
|
||||
|
||||
private void customizeRelaxedQueryChars(ConfigurableTomcatWebServerFactory factory, String relaxedChars) {
|
||||
factory.addConnectorCustomizers((connector) -> connector.setAttribute("relaxedQueryChars", relaxedChars));
|
||||
}
|
||||
|
||||
private void customizeRelaxedPathChars(ConfigurableTomcatWebServerFactory factory, String relaxedChars) {
|
||||
factory.addConnectorCustomizers((connector) -> connector.setAttribute("relaxedPathChars", relaxedChars));
|
||||
private String joinCharacters(List<Character> content) {
|
||||
return content.stream().map(String::valueOf).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private void customizeRemoteIpValve(ConfigurableTomcatWebServerFactory factory) {
|
||||
|
||||
@@ -2089,6 +2089,76 @@
|
||||
}
|
||||
],
|
||||
"hints": [
|
||||
{
|
||||
"name": "server.tomcat.relaxed-query-chars",
|
||||
"values": [
|
||||
{
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"value": ">"
|
||||
},
|
||||
{
|
||||
"value": "["
|
||||
},
|
||||
{
|
||||
"value": "\\"
|
||||
},
|
||||
{
|
||||
"value": "]"
|
||||
},
|
||||
{
|
||||
"value": "^"
|
||||
},
|
||||
{
|
||||
"value": "`"
|
||||
},
|
||||
{
|
||||
"value": "{"
|
||||
},
|
||||
{
|
||||
"value": "|"
|
||||
},
|
||||
{
|
||||
"value": "}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "server.tomcat.relaxed-path-chars",
|
||||
"values": [
|
||||
{
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"value": ">"
|
||||
},
|
||||
{
|
||||
"value": "["
|
||||
},
|
||||
{
|
||||
"value": "\\"
|
||||
},
|
||||
{
|
||||
"value": "]"
|
||||
},
|
||||
{
|
||||
"value": "^"
|
||||
},
|
||||
{
|
||||
"value": "`"
|
||||
},
|
||||
{
|
||||
"value": "{"
|
||||
},
|
||||
{
|
||||
"value": "|"
|
||||
},
|
||||
{
|
||||
"value": "}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "spring.liquibase.change-log",
|
||||
"providers": [
|
||||
|
||||
@@ -127,8 +127,8 @@ class ServerPropertiesTests {
|
||||
map.put("server.tomcat.remote-ip-header", "Remote-Ip");
|
||||
map.put("server.tomcat.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||
map.put("server.tomcat.background-processor-delay", "10");
|
||||
map.put("server.tomcat.relaxed-path-chars", "|");
|
||||
map.put("server.tomcat.relaxed-query-chars", "^^");
|
||||
map.put("server.tomcat.relaxed-path-chars", "|,<");
|
||||
map.put("server.tomcat.relaxed-query-chars", "^ , | ");
|
||||
bind(map);
|
||||
ServerProperties.Tomcat tomcat = this.properties.getTomcat();
|
||||
Accesslog accesslog = tomcat.getAccesslog();
|
||||
@@ -148,8 +148,8 @@ class ServerPropertiesTests {
|
||||
assertThat(tomcat.getProtocolHeader()).isEqualTo("X-Forwarded-Protocol");
|
||||
assertThat(tomcat.getInternalProxies()).isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||
assertThat(tomcat.getBackgroundProcessorDelay()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(tomcat.getRelaxedPathChars()).isEqualTo("|");
|
||||
assertThat(tomcat.getRelaxedQueryChars()).isEqualTo("^^");
|
||||
assertThat(tomcat.getRelaxedPathChars()).containsExactly('|', '<');
|
||||
assertThat(tomcat.getRelaxedQueryChars()).containsExactly('^', '|');
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -198,6 +198,22 @@ class TomcatWebServerFactoryCustomizerTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customRelaxedPathChars() {
|
||||
bind("server.tomcat.relaxed-path-chars=|,^");
|
||||
customizeAndRunServer((server) -> assertThat(
|
||||
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
|
||||
.getRelaxedPathChars()).isEqualTo("|^"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customRelaxedQueryChars() {
|
||||
bind("server.tomcat.relaxed-query-chars=^ , | ");
|
||||
customizeAndRunServer((server) -> assertThat(
|
||||
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
|
||||
.getRelaxedQueryChars()).isEqualTo("^|"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deduceUseForwardHeaders() {
|
||||
this.environment.setProperty("DYNO", "-");
|
||||
|
||||
Reference in New Issue
Block a user