From ed88edd3a89614da7cbe9af0f9c4e67883301385 Mon Sep 17 00:00:00 2001 From: Marta Medio Date: Tue, 1 Mar 2022 11:16:44 +0100 Subject: [PATCH] Updates RequestHeaderSize existing filter to also take into account key size Fixes gh-2536 --- .../main/asciidoc/spring-cloud-gateway.adoc | 23 +++++++++++++++++++ ...RequestHeaderSizeGatewayFilterFactory.java | 10 ++++---- ...estHeaderSizeGatewayFilterFactoryTest.java | 14 ++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-gateway.adoc b/docs/src/main/asciidoc/spring-cloud-gateway.adoc index c3935e9c..ef2c7b4e 100644 --- a/docs/src/main/asciidoc/spring-cloud-gateway.adoc +++ b/docs/src/main/asciidoc/spring-cloud-gateway.adoc @@ -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. diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactory.java index 8c3c80f3..e8edcc46 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactory.java @@ -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> headerEntry : headers.entrySet()) { + headerSizeInBytes += (long) headerEntry.getKey().getBytes().length; List 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(); } }; } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactoryTest.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactoryTest.java index c0dcf5d9..8f56f0ea 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactoryTest.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderSizeGatewayFilterFactoryTest.java @@ -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(); }