Updates RequestHeaderSize existing filter to also take into account key size

Fixes gh-2536
This commit is contained in:
Marta Medio
2022-03-01 11:16:44 +01:00
committed by spencergibb
parent 0dd2a47d8d
commit ed88edd3a8
3 changed files with 42 additions and 5 deletions

View File

@@ -1143,6 +1143,29 @@ spring:
This will remove the `red` parameter before it is sent downstream.
=== `RequestHeaderSize` `GatewayFilter` Factory
The `RequestHeaderSize` `GatewayFilter` factory takes a `maxSize` parameter.
It is the maximum data size allowed of the request header (incuding key and value).
The following listing configures a `RequestHeaderSize` `GatewayFilter`:
.application.yml
====
[source,yaml]
----
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B
----
====
This will send a status 431 if size of any request header is greater than 1000 Bytes.
=== The `RewritePath` `GatewayFilter` Factory
The `RewritePath` `GatewayFilter` factory takes a path `regexp` parameter and a `replacement` parameter.

View File

@@ -34,11 +34,12 @@ import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
/**
* This filter validates the size of each Request Header in the request. If size of any of
* the request header is greater than the configured maxSize,it blocks the request.
* Default max size of request header is 16KB.
* This filter validates the size of each Request Header in the request, including the
* key. If size of the request header is greater than the configured maxSize, it blocks
* the request. Default max size of request header is 16KB.
*
* @author Sakalya Deshpande
* @author Marta Medio
*/
public class RequestHeaderSizeGatewayFilterFactory
@@ -66,6 +67,7 @@ public class RequestHeaderSizeGatewayFilterFactory
Long headerSizeInBytes = 0L;
for (Map.Entry<String, List<String>> headerEntry : headers.entrySet()) {
headerSizeInBytes += (long) headerEntry.getKey().getBytes().length;
List<String> values = headerEntry.getValue();
for (String value : values) {
headerSizeInBytes += (long) value.getBytes().length;
@@ -86,7 +88,7 @@ public class RequestHeaderSizeGatewayFilterFactory
@Override
public String toString() {
return filterToStringCreator(RequestHeaderSizeGatewayFilterFactory.this)
.append("max", config.getMaxSize()).toString();
.append("maxSize", config.getMaxSize()).toString();
}
};
}

View File

@@ -39,6 +39,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
/**
* @author Sakalya Deshpande
* @author Marta Medio
*/
@SpringBootTest(webEnvironment = RANDOM_PORT)
@@ -64,12 +65,20 @@ public class RequestHeaderSizeGatewayFilterFactoryTest extends BaseWebClientTest
.valueMatches("errorMessage", responseMesssage);
}
@Test
public void setRequestHeaderSizeFilterTakesIntoAccountHeaderName() {
testClient.get().uri("/headerName").header("Host", "www.testrequestheadersizefiltername.org")
.header("HeaderName", "X").exchange().expectStatus()
.isEqualTo(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE).expectHeader()
.valueMatches("errorMessage", responseMesssage);
}
@Test
public void toStringFormat() {
Config config = new Config();
config.setMaxSize(DataSize.ofBytes(1000L));
GatewayFilter filter = new RequestHeaderSizeGatewayFilterFactory().apply(config);
assertThat(filter.toString()).contains("max").contains("1000B");
assertThat(filter.toString()).contains("maxSize").contains("1000B");
}
@EnableAutoConfiguration
@@ -86,6 +95,9 @@ public class RequestHeaderSizeGatewayFilterFactoryTest extends BaseWebClientTest
.route("test_request_header_size",
r -> r.order(-1).host("**.testrequestheadersizefilter.org")
.filters(f -> f.setRequestHeaderSize(DataSize.of(46L, DataUnit.BYTES))).uri(uri))
.route("test_request_header_size_name",
r -> r.order(1).host("**.testrequestheadersizefiltername.org")
.filters(f -> f.setRequestHeaderSize(DataSize.of(1L, DataUnit.BYTES))).uri(uri))
.build();
}