From 2d266a540e33ea47a21a25cd5a8cda4eab73856b Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 1 Nov 2021 17:50:56 -0400 Subject: [PATCH] Adds non-duplicate/non-sensitive headers from original request. --- .../cloud/gateway/mvc/ProxyExchange.java | 17 ++++++++++++++++- .../mvc/ProductionConfigurationTests.java | 11 +++++------ .../webflux/ProductionConfigurationTests.java | 14 +++++++------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java index 394d99a8..c98d6f04 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java @@ -23,7 +23,9 @@ import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; @@ -344,17 +346,30 @@ public class ProxyExchange { return rest.exchange(requestEntity, ParameterizedTypeReference.forType(responseType)); } + private void addHeaders(HttpHeaders headers) { + ArrayList headerNames = new ArrayList<>(); + webRequest.getHeaderNames().forEachRemaining(headerNames::add); + Set filteredKeys = filterHeaderKeys(headerNames); + filteredKeys.stream().filter(key -> !headers.containsKey(key)) + .forEach(header -> headers.addAll(header, Arrays.asList(webRequest.getHeaderValues(header)))); + } + private BodyBuilder headers(BodyBuilder builder) { proxy(); for (String name : filterHeaderKeys(headers)) { builder.header(name, headers.get(name).toArray(new String[0])); } + builder.headers(this::addHeaders); return builder; } private Set filterHeaderKeys(HttpHeaders headers) { + return filterHeaderKeys(headers.keySet()); + } + + private Set filterHeaderKeys(Collection headerNames) { final Set sensitiveHeaders = this.sensitive != null ? this.sensitive : DEFAULT_SENSITIVE; - return headers.keySet().stream().filter(header -> !sensitiveHeaders.contains(header.toLowerCase())) + return headerNames.stream().filter(header -> !sensitiveHeaders.contains(header.toLowerCase())) .collect(Collectors.toSet()); } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java index c519e360..c2430e9c 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java @@ -239,18 +239,17 @@ public class ProductionConfigurationTests { @Test @SuppressWarnings({ "Duplicates", "unchecked" }) public void testSensitiveHeadersOverride() throws Exception { - Map> headers = rest - .exchange( - RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers")) - .header("foo", "bar").header("abc", "xyz").header("cookie", "monster").build(), - Map.class) - .getBody(); + RequestEntity request = RequestEntity + .get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers")).header("foo", "bar") + .header("abc", "xyz").header("cookie", "monster").build(); + Map> headers = rest.exchange(request, Map.class).getBody(); assertThat(headers).doesNotContainKey("foo").doesNotContainKey("hello").containsKeys("bar", "abc"); assertThat(headers.get("cookie")).containsOnly("monster"); } @Test + @SuppressWarnings({ "Duplicates", "unchecked" }) public void testSensitiveHeadersDefault() throws Exception { Map> headers = rest.exchange(RequestEntity .get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/sensitive-headers-default")) diff --git a/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java index a508d2df..b2351a76 100644 --- a/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java +++ b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java @@ -178,8 +178,10 @@ public class ProductionConfigurationTests { @SuppressWarnings({ "Duplicates", "unchecked" }) public void testSensitiveHeadersOverride() throws Exception { Map> headers = rest - .exchange(RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers")) - .header("foo", "bar").header("abc", "xyz").header("cookie", "monster").build(), Map.class) + .exchange( + RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers")) + .header("foo", "bar").header("abc", "xyz").header("cookie", "monster").build(), + Map.class) .getBody(); assertThat(headers).doesNotContainKey("foo").doesNotContainKey("hello").containsKeys("bar", "abc"); @@ -188,11 +190,9 @@ public class ProductionConfigurationTests { @Test public void testSensitiveHeadersDefault() throws Exception { - Map> headers = rest - .exchange(RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/sensitive-headers-default")) - .header("cookie", "monster") - .build(), Map.class) - .getBody(); + Map> headers = rest.exchange(RequestEntity + .get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/sensitive-headers-default")) + .header("cookie", "monster").build(), Map.class).getBody(); assertThat(headers).doesNotContainKey("cookie"); }