diff --git a/docs/pom.xml b/docs/pom.xml index 83097fcc..eb901661 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT spring-cloud-gateway-docs jar diff --git a/pom.xml b/pom.xml index 0895de20..4ad1a1c9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT pom Spring Cloud Gateway @@ -15,7 +15,7 @@ org.springframework.cloud spring-cloud-build - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT @@ -55,8 +55,8 @@ 1.0.8.RELEASE 17 2.3.0 - 3.3.1-SNAPSHOT - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT + 5.0.0-SNAPSHOT 4.3.1-SNAPSHOT 4.3.1-SNAPSHOT diff --git a/spring-cloud-gateway-dependencies/pom.xml b/spring-cloud-gateway-dependencies/pom.xml index 44736442..8809948e 100644 --- a/spring-cloud-gateway-dependencies/pom.xml +++ b/spring-cloud-gateway-dependencies/pom.xml @@ -6,12 +6,12 @@ spring-cloud-dependencies-parent org.springframework.cloud - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT spring-cloud-gateway-dependencies - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT pom spring-cloud-gateway-dependencies diff --git a/spring-cloud-gateway-integration-tests/grpc/pom.xml b/spring-cloud-gateway-integration-tests/grpc/pom.xml index bb1ac76d..6ea9875e 100644 --- a/spring-cloud-gateway-integration-tests/grpc/pom.xml +++ b/spring-cloud-gateway-integration-tests/grpc/pom.xml @@ -18,7 +18,7 @@ org.springframework.cloud spring-cloud-gateway-integration-tests - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-integration-tests/http2/pom.xml b/spring-cloud-gateway-integration-tests/http2/pom.xml index ee87577b..7c4aafcd 100644 --- a/spring-cloud-gateway-integration-tests/http2/pom.xml +++ b/spring-cloud-gateway-integration-tests/http2/pom.xml @@ -16,7 +16,7 @@ org.springframework.cloud spring-cloud-gateway-integration-tests - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-integration-tests/httpclient/pom.xml b/spring-cloud-gateway-integration-tests/httpclient/pom.xml index 32aa3ae3..1b2c6247 100644 --- a/spring-cloud-gateway-integration-tests/httpclient/pom.xml +++ b/spring-cloud-gateway-integration-tests/httpclient/pom.xml @@ -16,7 +16,7 @@ org.springframework.cloud spring-cloud-gateway-integration-tests - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml index bab5a654..d19c82b9 100644 --- a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml +++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml @@ -16,7 +16,7 @@ org.springframework.cloud spring-cloud-gateway-integration-tests - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-integration-tests/pom.xml b/spring-cloud-gateway-integration-tests/pom.xml index b2e3dc7a..01c5c17d 100644 --- a/spring-cloud-gateway-integration-tests/pom.xml +++ b/spring-cloud-gateway-integration-tests/pom.xml @@ -16,7 +16,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-mvc/pom.xml b/spring-cloud-gateway-mvc/pom.xml index feb0d076..65d55f7a 100644 --- a/spring-cloud-gateway-mvc/pom.xml +++ b/spring-cloud-gateway-mvc/pom.xml @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. 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 11eb688c..a03f2039 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 @@ -365,7 +365,7 @@ public class ProxyExchange { webRequest.getHeaderNames().forEachRemaining(headerNames::add); Set filteredKeys = filterHeaderKeys(headerNames); filteredKeys.stream() - .filter(key -> !headers.containsKey(key)) + .filter(key -> !headers.containsHeader(key)) .forEach(header -> headers.addAll(header, Arrays.asList(webRequest.getHeaderValues(header)))); } @@ -379,7 +379,7 @@ public class ProxyExchange { } private Set filterHeaderKeys(HttpHeaders headers) { - return filterHeaderKeys(headers.keySet()); + return filterHeaderKeys(headers.headerNames()); } private Set filterHeaderKeys(Collection headerNames) { @@ -529,7 +529,7 @@ public class ProxyExchange { @Override public Enumeration getHeaderNames() { - Set names = headers.keySet(); + Set names = headers.headerNames(); if (names.isEmpty()) { return super.getHeaderNames(); } diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/config/ProxyResponseAutoConfiguration.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/config/ProxyResponseAutoConfiguration.java index b7cfeb18..7ad6ab2d 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/config/ProxyResponseAutoConfiguration.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/config/ProxyResponseAutoConfiguration.java @@ -25,6 +25,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -97,17 +98,15 @@ public class ProxyResponseAutoConfiguration implements WebMvcConfigurer { private static class NoOpResponseErrorHandler extends DefaultResponseErrorHandler { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - @Override public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { + } @Override - protected void handleError(ClientHttpResponse response, HttpStatusCode statusCode, URI url, HttpMethod method) - throws IOException { + protected void handleError(ClientHttpResponse response, HttpStatusCode statusCode, @Nullable URI url, + @Nullable HttpMethod method) throws IOException { + } } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java index ea506dbb..7cf67e45 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java @@ -21,6 +21,7 @@ import java.net.URI; import java.util.Collections; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -39,6 +40,7 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpResponse; @@ -193,7 +195,14 @@ public class GetWithBodyRequestTests { private static class NoOpResponseErrorHandler extends DefaultResponseErrorHandler { @Override - public void handleError(ClientHttpResponse response) throws IOException { + public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { + + } + + @Override + protected void handleError(ClientHttpResponse response, HttpStatusCode statusCode, @Nullable URI url, + @Nullable HttpMethod method) throws IOException { + } } 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 d426f2d1..4468de25 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 @@ -558,7 +558,7 @@ public class ProductionConfigurationTests { @GetMapping("/headers") public Map> headers(@RequestHeader HttpHeaders headers) { - return new LinkedMultiValueMap<>(headers); + return new LinkedMultiValueMap<>(headers.asMultiValueMap()); } } diff --git a/spring-cloud-gateway-proxyexchange-webflux/pom.xml b/spring-cloud-gateway-proxyexchange-webflux/pom.xml index 2f9f809b..96c7f7bc 100644 --- a/spring-cloud-gateway-proxyexchange-webflux/pom.xml +++ b/spring-cloud-gateway-proxyexchange-webflux/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-proxyexchange-webflux diff --git a/spring-cloud-gateway-proxyexchange-webmvc/pom.xml b/spring-cloud-gateway-proxyexchange-webmvc/pom.xml index 3b833bb2..650cbb80 100644 --- a/spring-cloud-gateway-proxyexchange-webmvc/pom.xml +++ b/spring-cloud-gateway-proxyexchange-webmvc/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-proxyexchange-webmvc diff --git a/spring-cloud-gateway-sample/pom.xml b/spring-cloud-gateway-sample/pom.xml index 5cf2cbde..d831a939 100644 --- a/spring-cloud-gateway-sample/pom.xml +++ b/spring-cloud-gateway-sample/pom.xml @@ -16,7 +16,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-server-mvc/pom.xml b/spring-cloud-gateway-server-mvc/pom.xml index 0991c38b..4ac794a8 100644 --- a/spring-cloud-gateway-server-mvc/pom.xml +++ b/spring-cloud-gateway-server-mvc/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-server-mvc diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctions.java index 14795efa..81daaaff 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctions.java @@ -133,12 +133,20 @@ public abstract class AfterFilterFunctions { String replacement = originalReplacement.replace("$\\", "$"); Pattern pattern = Pattern.compile(regexp); return (request, response) -> { - response.headers().computeIfPresent(name, (key, values) -> { + BiFunction, List> remappingFunction = (key, values) -> { List rewrittenValues = values.stream() - .map(value -> pattern.matcher(value).replaceAll(replacement)) - .toList(); + .map(value -> pattern.matcher(value).replaceAll(replacement)) + .toList(); return new ArrayList<>(rewrittenValues); - }); + }; + if (response.headers().get(name) != null) { + List oldValue = response.headers().get(name); + List newValue = remappingFunction.apply(name, oldValue); + if (newValue != null) + response.headers().put(name, newValue); + else + response.headers().remove(name); + } return response; }; } diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java index ce2b2404..2cfa467d 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java @@ -171,7 +171,7 @@ public abstract class BeforeFilterFunctions { public static Function mapRequestHeader(String fromHeader, String toHeader) { return request -> { - if (request.headers().asHttpHeaders().containsKey(fromHeader)) { + if (request.headers().asHttpHeaders().containsHeader(fromHeader)) { List values = request.headers().header(fromHeader); return ServerRequest.from(request).header(toHeader, values.toArray(new String[0])).build(); } @@ -281,7 +281,7 @@ public abstract class BeforeFilterFunctions { public static Function requestHeaderToRequestUri(String name) { return request -> { - if (request.headers().asHttpHeaders().containsKey(name)) { + if (request.headers().asHttpHeaders().containsHeader(name)) { String newUri = request.headers().firstHeader(name); try { MvcUtils.setRequestUrl(request, new URI(newUri)); @@ -302,7 +302,7 @@ public abstract class BeforeFilterFunctions { Assert.notNull(maxSize, "maxSize may not be null"); Assert.isTrue(maxSize.toBytes() > 0, "maxSize must be greater than 0"); return request -> { - if (request.headers().asHttpHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)) { + if (request.headers().asHttpHeaders().containsHeader(HttpHeaders.CONTENT_LENGTH)) { long contentLength = request.headers().asHttpHeaders().getContentLength(); if (contentLength > maxSize.toBytes()) { String errorMessage = String.format(REQUEST_SIZE_ERROR_MSG, DataSize.ofBytes(contentLength), diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctions.java index 6c50f63d..4fe90779 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctions.java @@ -304,12 +304,6 @@ public abstract class BodyFilterFunctions { return delegate.method(); } - @Override - @Deprecated - public String methodName() { - return delegate.methodName(); - } - @Override public URI uri() { return delegate.uri(); @@ -325,12 +319,6 @@ public abstract class BodyFilterFunctions { return delegate.path(); } - @Override - @Deprecated - public PathContainer pathContainer() { - return delegate.pathContainer(); - } - @Override public RequestPath requestPath() { return delegate.requestPath(); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/LoadBalancerFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/LoadBalancerFilterFunctions.java index db7b1464..b2fe526d 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/LoadBalancerFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/LoadBalancerFilterFunctions.java @@ -42,6 +42,7 @@ import org.springframework.cloud.gateway.server.mvc.common.MvcUtils; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.servlet.function.HandlerFilterFunction; @@ -135,7 +136,7 @@ public abstract class LoadBalancerFilterFunctions { } private static MultiValueMap buildCookies(MultiValueMap cookies) { - HttpHeaders newCookies = new HttpHeaders(); + LinkedMultiValueMap newCookies = new LinkedMultiValueMap<>(cookies.size()); if (cookies != null) { cookies.forEach((key, value) -> value .forEach(cookie -> newCookies.put(cookie.getName(), Collections.singletonList(cookie.getValue())))); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveContentLengthRequestHeadersFilter.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveContentLengthRequestHeadersFilter.java index 1c6818bd..fb4a73bd 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveContentLengthRequestHeadersFilter.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveContentLengthRequestHeadersFilter.java @@ -31,7 +31,7 @@ public class RemoveContentLengthRequestHeadersFilter implements HttpHeadersFilte @Override public HttpHeaders apply(HttpHeaders input, ServerRequest request) { - if (input.containsKey(HttpHeaders.CONTENT_LENGTH)) { + if (input.containsHeader(HttpHeaders.CONTENT_LENGTH)) { HttpHeaders filtered = new HttpHeaders(); // avoids read only if input is read only diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveHttp2StatusResponseHeadersFilter.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveHttp2StatusResponseHeadersFilter.java index 36551378..4b2b7f6c 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveHttp2StatusResponseHeadersFilter.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RemoveHttp2StatusResponseHeadersFilter.java @@ -31,7 +31,7 @@ public class RemoveHttp2StatusResponseHeadersFilter implements HttpHeadersFilter @Override public HttpHeaders apply(HttpHeaders input, ServerResponse serverResponse) { - if (input.containsKey(":status")) { + if (input.containsHeader(":status")) { HttpHeaders filtered = new HttpHeaders(); filtered.addAll(input); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilter.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilter.java index dd55b72d..8077e4ae 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilter.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilter.java @@ -32,7 +32,7 @@ public class TransferEncodingNormalizationRequestHeadersFilter public HttpHeaders apply(HttpHeaders input, ServerRequest request) { String transferEncoding = input.getFirst(HttpHeaders.TRANSFER_ENCODING); if (transferEncoding != null && "chunked".equalsIgnoreCase(transferEncoding.trim()) - && input.containsKey(HttpHeaders.CONTENT_LENGTH)) { + && input.containsHeader(HttpHeaders.CONTENT_LENGTH)) { HttpHeaders filtered = new HttpHeaders(); // avoids read only if input is read only diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilter.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilter.java index 48f809cc..20cf240a 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilter.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilter.java @@ -199,7 +199,7 @@ public class XForwardedRequestHeadersFilter implements HttpHeadersFilter.Request headers.add(name, value); } // these headers should be treated as a single comma separated header - if (headers.containsKey(name)) { + if (headers.containsHeader(name)) { List values = headers.get(name).stream().filter(shouldWrite).toList(); String delimitedValue = StringUtils.collectionToCommaDelimitedString(values); headers.set(name, delimitedValue); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/AbstractGatewayServerResponse.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/AbstractGatewayServerResponse.java index 2f4e5b4c..e2ccfb5f 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/AbstractGatewayServerResponse.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/AbstractGatewayServerResponse.java @@ -55,7 +55,7 @@ abstract class AbstractGatewayServerResponse extends GatewayErrorHandlingServerR MultiValueMap cookies) { this.statusCode = statusCode; - this.headers = HttpHeaders.writableHttpHeaders(headers); + this.headers = HttpHeaders.copyOf(headers); this.cookies = new LinkedMultiValueMap<>(cookies); } @@ -69,12 +69,6 @@ abstract class AbstractGatewayServerResponse extends GatewayErrorHandlingServerR this.statusCode = statusCode; } - @Override - @Deprecated - public int rawStatusCode() { - return this.statusCode.value(); - } - @Override public final HttpHeaders headers() { return this.headers; diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerHeaderUtils.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerHeaderUtils.java index 891f05c1..bfbcf81d 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerHeaderUtils.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerHeaderUtils.java @@ -61,7 +61,7 @@ public final class FunctionHandlerHeaderUtils { for (String name : headers.keySet()) { Object value = headers.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !ignoredHeders.contains(name)) { + if (!IGNORED.containsHeader(name) && !ignoredHeders.contains(name)) { Collection values = multi(value); for (Object object : values) { result.set(name, object.toString()); @@ -79,10 +79,10 @@ public final class FunctionHandlerHeaderUtils { public static HttpHeaders sanitize(HttpHeaders request, List ignoredHeders, List requestOnlyHeaders) { HttpHeaders result = new HttpHeaders(); - for (String name : request.keySet()) { + for (String name : request.headerNames()) { List value = request.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !REQUEST_ONLY.containsKey(name) && !ignoredHeders.contains(name) + if (!IGNORED.containsHeader(name) && !REQUEST_ONLY.containsHeader(name) && !ignoredHeders.contains(name) && !requestOnlyHeaders.contains(name)) { result.put(name, value); } @@ -97,7 +97,7 @@ public final class FunctionHandlerHeaderUtils { public static MessageHeaders fromHttp(HttpHeaders headers) { Map map = new LinkedHashMap<>(); - for (String name : headers.keySet()) { + for (String name : headers.headerNames()) { Collection values = multi(headers.get(name)); name = name.toLowerCase(Locale.ROOT); Object value = values == null ? null : (values.size() == 1 ? values.iterator().next() : values); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/GatewayAsyncServerResponse.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/GatewayAsyncServerResponse.java index 5e388040..9e55d479 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/GatewayAsyncServerResponse.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/handler/GatewayAsyncServerResponse.java @@ -85,12 +85,6 @@ final class GatewayAsyncServerResponse extends GatewayErrorHandlingServerRespons return delegate(ServerResponse::statusCode); } - @Override - @Deprecated - public int rawStatusCode() { - return delegate(ServerResponse::rawStatusCode); - } - @Override public HttpHeaders headers() { return delegate(ServerResponse::headers); diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/predicate/GatewayRequestPredicates.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/predicate/GatewayRequestPredicates.java index c25671da..dc735ce7 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/predicate/GatewayRequestPredicates.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/predicate/GatewayRequestPredicates.java @@ -345,12 +345,6 @@ public abstract class GatewayRequestPredicates { super.setPathOptions(PathContainer.Options.MESSAGE_ROUTE); } - @SuppressWarnings("deprecation") - @Override - public void setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) { - raiseError(); - } - @Override public void setCaseSensitive(boolean caseSensitive) { raiseError(); diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfigurationTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfigurationTests.java index 01f8f9f4..51c26aa6 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfigurationTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/GatewayServerMvcAutoConfigurationTests.java @@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigu import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.http.client.SimpleClientHttpRequestFactoryBuilder; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -158,7 +159,7 @@ public class GatewayServerMvcAutoConfigurationTests { assertThat(settings.readTimeout()).isEqualTo(Duration.ofSeconds(2)); assertThat(settings.connectTimeout()).isEqualTo(Duration.ofSeconds(1)); assertThat(settings.sslBundle()).isNotNull(); - assertThat(settings.redirects()).isEqualTo(ClientHttpRequestFactorySettings.Redirects.DONT_FOLLOW); + assertThat(settings.redirects()).isEqualTo(HttpRedirects.DONT_FOLLOW); } @Test diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java index 79929111..f0af00b4 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java @@ -337,7 +337,7 @@ public class ServerMvcIntegrationTests { Map map = res.getResponseBody(); Map headers = getMap(map, "headers"); assertThat(headers).doesNotContainKey("x-bar"); - assertThat(res.getResponseHeaders()).containsEntry("x-bar", Collections.singletonList("val1")); + assertThat(res.getResponseHeaders().asMultiValueMap()).containsEntry("x-bar", Collections.singletonList("val1")); }); } @@ -739,7 +739,7 @@ public class ServerMvcIntegrationTests { .isOk() .expectBody(Map.class) .consumeWith(res -> { - HttpHeaders headers = res.getResponseHeaders(); + MultiValueMap headers = res.getResponseHeaders().asMultiValueMap(); assertThat(headers).doesNotContainEntry("X-Test", List.of("value1")); assertThat(headers).containsEntry("X-Test", List.of("value2")); }); diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/TokenRelayFilterFunctionsTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/TokenRelayFilterFunctionsTests.java index 8f9a03b8..f66f3b57 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/TokenRelayFilterFunctionsTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/TokenRelayFilterFunctionsTests.java @@ -75,7 +75,7 @@ public class TokenRelayFilterFunctionsTests { @Test public void emptyPrincipal() throws Exception { filter.filter(ServerRequest.create(request, converters), req -> { - assertThat(req.headers().asHttpHeaders().containsKey(HttpHeaders.AUTHORIZATION)).isFalse(); + assertThat(req.headers().asHttpHeaders().containsHeader(HttpHeaders.AUTHORIZATION)).isFalse(); return null; }); } @@ -131,7 +131,7 @@ public class TokenRelayFilterFunctionsTests { public void principalIsNotOAuth2AuthenticationToken() throws Exception { request.setUserPrincipal(new TestingAuthenticationToken("my", null)); filter.filter(ServerRequest.create(request, converters), req -> { - assertThat(req.headers().asHttpHeaders().containsKey(HttpHeaders.AUTHORIZATION)).isFalse(); + assertThat(req.headers().asHttpHeaders().containsHeader(HttpHeaders.AUTHORIZATION)).isFalse(); return null; }); } diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/ForwardedRequestHeadersFilterTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/ForwardedRequestHeadersFilterTests.java index f823bde8..0d46d7b4 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/ForwardedRequestHeadersFilterTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/ForwardedRequestHeadersFilterTests.java @@ -270,7 +270,7 @@ public class ForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).doesNotContainKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).doesNotContain(FORWARDED_HEADER); } // verify that existing forwarded header is not forwarded if not trusted @@ -288,7 +288,7 @@ public class ForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).containsKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).contains(FORWARDED_HEADER); List forwardedHeaders = headers.get(FORWARDED_HEADER); Optional filtered = forwardedHeaders.stream().filter(value -> value.contains("127.0.0.1")).findFirst(); assertThat(filtered).isEmpty(); @@ -309,7 +309,7 @@ public class ForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).containsKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).contains(FORWARDED_HEADER); List forwardedHeaders = headers.get(FORWARDED_HEADER); Optional filtered = forwardedHeaders.stream().filter(value -> value.contains("127.0.0.1")).findFirst(); assertThat(filtered).isEmpty(); diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilterTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilterTests.java index 11c1a779..2de6e1c9 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilterTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/TransferEncodingNormalizationRequestHeadersFilterTests.java @@ -36,7 +36,7 @@ public class TransferEncodingNormalizationRequestHeadersFilterTests { .buildRequest(null); HttpHeaders headers = testFilter(ServerRequest.create(servletRequest, Collections.emptyList())); - assertThat(headers).containsKey(HttpHeaders.CONTENT_LENGTH).doesNotContainKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).contains(HttpHeaders.CONTENT_LENGTH).doesNotContain(HttpHeaders.TRANSFER_ENCODING); } @Test @@ -47,7 +47,7 @@ public class TransferEncodingNormalizationRequestHeadersFilterTests { .buildRequest(null); HttpHeaders headers = testFilter(ServerRequest.create(servletRequest, Collections.emptyList())); - assertThat(headers).doesNotContainKey(HttpHeaders.CONTENT_LENGTH).containsKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).doesNotContain(HttpHeaders.CONTENT_LENGTH).contains(HttpHeaders.TRANSFER_ENCODING); } @Test @@ -58,7 +58,7 @@ public class TransferEncodingNormalizationRequestHeadersFilterTests { .buildRequest(null); HttpHeaders headers = testFilter(ServerRequest.create(servletRequest, Collections.emptyList())); - assertThat(headers).doesNotContainKey(HttpHeaders.CONTENT_LENGTH).containsKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).doesNotContain(HttpHeaders.CONTENT_LENGTH).contains(HttpHeaders.TRANSFER_ENCODING); } private HttpHeaders testFilter(ServerRequest request) { diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilterTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilterTests.java index e636b578..84a091cc 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilterTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/XForwardedRequestHeadersFilterTests.java @@ -59,8 +59,8 @@ public class XForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).doesNotContainKeys(X_FORWARDED_FOR_HEADER) - .containsKeys(X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).doesNotContain(X_FORWARDED_FOR_HEADER) + .contains(X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("myhost"); assertThat(headers.getFirst(X_FORWARDED_PORT_HEADER)).isEqualTo("80"); @@ -114,7 +114,7 @@ public class XForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).doesNotContainKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, + assertThat(headers.headerNames()).doesNotContain(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); } @@ -135,7 +135,7 @@ public class XForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).doesNotContain("127.0.0.1") @@ -156,7 +156,7 @@ public class XForwardedRequestHeadersFilterTests { HttpHeaders headers = filter.apply(request.headers().asHttpHeaders(), request); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).doesNotContain("127.0.0.1"); diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/TestAutoConfiguration.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/TestAutoConfiguration.java index c9457cb1..c4227bc4 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/TestAutoConfiguration.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/TestAutoConfiguration.java @@ -35,7 +35,7 @@ public class TestAutoConfiguration { @Bean RestTemplateCustomizer testRestClientRestTemplateCustomizer() { return restTemplate -> restTemplate.setClientHttpRequestInitializers(List.of(request -> { - if (!request.getHeaders().containsKey(HttpHeaders.ACCEPT)) { + if (!request.getHeaders().containsHeader(HttpHeaders.ACCEPT)) { request.getHeaders().setAccept(List.of(MediaType.ALL)); } })); diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/client/HeaderAssertions.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/client/HeaderAssertions.java index 6e56a0e8..9960cf09 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/client/HeaderAssertions.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/client/HeaderAssertions.java @@ -210,7 +210,7 @@ public class HeaderAssertions { * @since 5.0.3 */ public TestRestClient.ResponseSpec exists(String name) { - if (!getHeaders().containsKey(name)) { + if (!getHeaders().containsHeader(name)) { String message = getMessage(name) + " does not exist"; this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(message)); } @@ -221,7 +221,7 @@ public class HeaderAssertions { * Expect that the header with the given name is not present. */ public TestRestClient.ResponseSpec doesNotExist(String name) { - if (getHeaders().containsKey(name)) { + if (getHeaders().containsHeader(name)) { String message = getMessage(name) + " exists with value=[" + getHeaders().getFirst(name) + "]"; this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(message)); } diff --git a/spring-cloud-gateway-server-webflux/pom.xml b/spring-cloud-gateway-server-webflux/pom.xml index 2fd314ab..7d3f98e3 100644 --- a/spring-cloud-gateway-server-webflux/pom.xml +++ b/spring-cloud-gateway-server-webflux/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-server-webflux diff --git a/spring-cloud-gateway-server-webmvc/pom.xml b/spring-cloud-gateway-server-webmvc/pom.xml index 0e81f0b1..44b044de 100644 --- a/spring-cloud-gateway-server-webmvc/pom.xml +++ b/spring-cloud-gateway-server-webmvc/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-server-webmvc diff --git a/spring-cloud-gateway-server/pom.xml b/spring-cloud-gateway-server/pom.xml index 9e576d2d..4cd63185 100644 --- a/spring-cloud-gateway-server/pom.xml +++ b/spring-cloud-gateway-server/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-gateway-server diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilter.java index e35227dd..8bd66f92 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilter.java @@ -153,8 +153,8 @@ public class FunctionRoutingFilter implements GlobalFilter, Ordered { ServerHttpResponse response = exchange.getResponse(); Mono messageBody = writeBody(response, outputMessage, outClass); HttpHeaders responseHeaders = response.getHeaders(); - if (!responseHeaders.containsKey(HttpHeaders.TRANSFER_ENCODING) - || responseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)) { + if (!responseHeaders.containsHeader(HttpHeaders.TRANSFER_ENCODING) + || responseHeaders.containsHeader(HttpHeaders.CONTENT_LENGTH)) { messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount())); } responseHeaders.addAll(newResponseHeaders); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java index 2350d4d2..650fe07c 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java @@ -171,8 +171,8 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered { HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(getHeadersFilters(), headers, exchange, Type.RESPONSE); - if (!filteredResponseHeaders.containsKey(HttpHeaders.TRANSFER_ENCODING) - && filteredResponseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)) { + if (!filteredResponseHeaders.containsHeader(HttpHeaders.TRANSFER_ENCODING) + && filteredResponseHeaders.containsHeader(HttpHeaders.CONTENT_LENGTH)) { // It is not valid to have both the transfer-encoding header and // the content-length header. // Remove the transfer-encoding header in the response if the @@ -180,7 +180,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered { response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING); } - exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES, filteredResponseHeaders.keySet()); + exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES, filteredResponseHeaders.headerNames()); response.getHeaders().addAll(filteredResponseHeaders); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/MapRequestHeaderGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/MapRequestHeaderGatewayFilterFactory.java index 05840164..fe1f3e5c 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/MapRequestHeaderGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/MapRequestHeaderGatewayFilterFactory.java @@ -59,7 +59,7 @@ public class MapRequestHeaderGatewayFilterFactory return new GatewayFilter() { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - if (!exchange.getRequest().getHeaders().containsKey(config.getFromHeader())) { + if (!exchange.getRequest().getHeaders().containsHeader(config.getFromHeader())) { return chain.filter(exchange); } List headerValues = exchange.getRequest().getHeaders().get(config.getFromHeader()); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RewriteResponseHeaderGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RewriteResponseHeaderGatewayFilterFactory.java index 98c3fd17..c0ecaee2 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RewriteResponseHeaderGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RewriteResponseHeaderGatewayFilterFactory.java @@ -81,7 +81,16 @@ public class RewriteResponseHeaderGatewayFilterFactory protected void rewriteHeaders(ServerWebExchange exchange, Config config) { final String name = config.getName(); final HttpHeaders responseHeaders = exchange.getResponse().getHeaders(); - responseHeaders.computeIfPresent(name, (k, v) -> rewriteHeaders(config, v)); + if (responseHeaders.get(name) != null) { + List oldValue = responseHeaders.get(name); + List newValue = rewriteHeaders(config, oldValue); + if (newValue != null) { + responseHeaders.put(name, newValue); + } + else { + responseHeaders.remove(name); + } + } } protected List rewriteHeaders(Config config, List headers) { diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactory.java index 188f4c40..e383c8bf 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactory.java @@ -188,7 +188,9 @@ public class SecureHeadersGatewayFilterFactory private void addHeaderIfEnabled(HttpHeaders headers, Set headersToAdd, String headerName, String headerValue) { if (headersToAdd.contains(headerName.toLowerCase(Locale.ROOT))) { - headers.addIfAbsent(headerName, headerValue); + if (!headers.containsHeader(headerName)) { + headers.add(headerName, headerValue); + } } } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java index 4e376ca2..37121986 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java @@ -232,8 +232,8 @@ public class ModifyResponseBodyGatewayFilterFactory return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> { Mono messageBody = writeBody(getDelegate(), outputMessage, outClass); HttpHeaders headers = getDelegate().getHeaders(); - if (!headers.containsKey(HttpHeaders.TRANSFER_ENCODING) - || headers.containsKey(HttpHeaders.CONTENT_LENGTH)) { + if (!headers.containsHeader(HttpHeaders.TRANSFER_ENCODING) + || headers.containsHeader(HttpHeaders.CONTENT_LENGTH)) { messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount())); } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilter.java index e393c1ec..633c5f29 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilter.java @@ -34,7 +34,7 @@ public class TransferEncodingNormalizationHeadersFilter implements HttpHeadersFi public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { String transferEncoding = input.getFirst(HttpHeaders.TRANSFER_ENCODING); if (transferEncoding != null && "chunked".equalsIgnoreCase(transferEncoding.trim()) - && input.containsKey(HttpHeaders.CONTENT_LENGTH)) { + && input.containsHeader(HttpHeaders.CONTENT_LENGTH)) { HttpHeaders filtered = new HttpHeaders(); // avoids read only if input is read only diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java index 6dca67d5..2f463374 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java @@ -325,7 +325,7 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered { headers.add(name, value); } // these headers should be treated as a single comma separated header - if (headers.containsKey(name)) { + if (headers.containsHeader(name)) { List values = headers.get(name).stream().filter(shouldWrite).toList(); String delimitedValue = StringUtils.collectionToCommaDelimitedString(values); headers.set(name, delimitedValue); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java index 45550df5..5993cac1 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java @@ -95,7 +95,8 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory apply(Config config) { final ArrayList pathPatterns = new ArrayList<>(); synchronized (this.pathPatternParser) { - pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash()); + // FIXME: 5.0.0 setMatchOptionalTrailingSeparator missing + // pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash()); config.getPatterns().forEach(pattern -> { String basePath = webFluxProperties.getBasePath(); boolean basePathIsNotBlank = StringUtils.hasText(basePath); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MessageHeaderUtils.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MessageHeaderUtils.java index 7916d77d..20acf6cb 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MessageHeaderUtils.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MessageHeaderUtils.java @@ -61,7 +61,7 @@ public final class MessageHeaderUtils { for (String name : headers.keySet()) { Object value = headers.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !ignoredHeders.contains(name)) { + if (!IGNORED.containsHeader(name) && !ignoredHeders.contains(name)) { Collection values = multi(value); for (Object object : values) { result.set(name, object.toString()); @@ -79,10 +79,10 @@ public final class MessageHeaderUtils { public static HttpHeaders sanitize(HttpHeaders request, List ignoredHeders, List requestOnlyHeaders) { HttpHeaders result = new HttpHeaders(); - for (String name : request.keySet()) { + for (String name : request.headerNames()) { List value = request.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !REQUEST_ONLY.containsKey(name) && !ignoredHeders.contains(name) + if (!IGNORED.containsHeader(name) && !REQUEST_ONLY.containsHeader(name) && !ignoredHeders.contains(name) && !requestOnlyHeaders.contains(name)) { result.put(name, value); } @@ -97,7 +97,7 @@ public final class MessageHeaderUtils { public static MessageHeaders fromHttp(HttpHeaders headers) { Map map = new LinkedHashMap<>(); - for (String name : headers.keySet()) { + for (String name : headers.headerNames()) { Collection values = multi(headers.get(name)); name = name.toLowerCase(Locale.ROOT); Object value = values == null ? null : (values.size() == 1 ? values.iterator().next() : values); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/tagsprovider/GatewayHttpTagsProvider.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/tagsprovider/GatewayHttpTagsProvider.java index 789e3bd7..0cfc5a2c 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/tagsprovider/GatewayHttpTagsProvider.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/tagsprovider/GatewayHttpTagsProvider.java @@ -40,7 +40,7 @@ public class GatewayHttpTagsProvider implements GatewayTagsProvider { // it needs to be checked for first, otherwise the delegate response // who's status DIDN'T change, will be used if (exchange.getResponse() instanceof AbstractServerHttpResponse) { - Integer statusInt = ((AbstractServerHttpResponse) exchange.getResponse()).getRawStatusCode(); + Integer statusInt = ((AbstractServerHttpResponse) exchange.getResponse()).getStatusCode().value(); if (statusInt != null) { status = String.valueOf(statusInt); httpStatusCodeStr = status; diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/GatewayMetricsFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/GatewayMetricsFilterTests.java index 5099290a..ac593916 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/GatewayMetricsFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/GatewayMetricsFilterTests.java @@ -84,7 +84,7 @@ public class GatewayMetricsFilterTests extends BaseWebClientTests { // cannot use netty client since we cannot read custom http status ResponseEntity response = new TestRestTemplate().exchange(baseUri + "/headers", HttpMethod.POST, new HttpEntity<>(headers), String.class); - assertThat(response.getStatusCodeValue()).isEqualTo(432); + assertThat(response.getStatusCode().value()).isEqualTo(432); assertMetricsContainsTag("outcome", "CUSTOM"); assertMetricsContainsTag("status", "432"); assertMetricsContainsTag("routeId", "test_custom_http_status_metrics"); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerServiceInstanceCookieFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerServiceInstanceCookieFilterTests.java index 5ecef788..67c1d1e0 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerServiceInstanceCookieFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerServiceInstanceCookieFilterTests.java @@ -92,7 +92,7 @@ class LoadBalancerServiceInstanceCookieFilterTests { void shouldContinueChainWhenNoServiceInstanceResponse() { ServerWebExchange filteredExchange = testFilter(exchange); - assertThat(filteredExchange.getRequest().getHeaders()).isEmpty(); + assertThat(filteredExchange.getRequest().getHeaders().isEmpty()).isTrue(); } @Test @@ -104,7 +104,7 @@ class LoadBalancerServiceInstanceCookieFilterTests { ServerWebExchange filteredExchange = testFilter(exchange); - assertThat(filteredExchange.getRequest().getHeaders()).isEmpty(); + assertThat(filteredExchange.getRequest().getHeaders().isEmpty()).isTrue(); } @Test @@ -116,7 +116,7 @@ class LoadBalancerServiceInstanceCookieFilterTests { ServerWebExchange filteredExchange = testFilter(exchange); - assertThat(filteredExchange.getRequest().getHeaders()).isEmpty(); + assertThat(filteredExchange.getRequest().getHeaders().isEmpty()).isTrue(); } private ServerWebExchange testFilter(ServerWebExchange exchange) { diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilterTests.java index 8b5be710..33c547b1 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilterTests.java @@ -106,12 +106,12 @@ public class WebsocketRoutingFilterTests { MockServerWebExchange exchange = MockServerWebExchange.from(request); exchange.getAttributes().put(PRESERVE_HOST_HEADER_ATTRIBUTE, preserveHostHeader); HttpHeaders httpHeaders = HttpHeadersFilter.filterRequest(filters, exchange); - assertThat(httpHeaders).doesNotContainKeys("Sec-Websocket-Something").containsKey("x-foo"); + assertThat(httpHeaders.headerNames()).doesNotContain("Sec-Websocket-Something").contains("x-foo"); if (preserveHostHeader) { - assertThat(httpHeaders).containsKey(HOST); + assertThat(httpHeaders.headerNames()).contains(HOST); } else { - assertThat(httpHeaders).doesNotContainKeys(HOST); + assertThat(httpHeaders.headerNames()).doesNotContain(HOST); } } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java index 5d1dfe53..358fc950 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java @@ -130,7 +130,7 @@ public class RequestRateLimiterGatewayFilterFactoryTests extends BaseWebClientTe Mono response = filter.filter(exchange, this.filterChain); response.subscribe(aVoid -> { assertThat(exchange.getResponse().getStatusCode()).isEqualTo(expectedStatus); - assertThat(exchange.getResponse().getHeaders()).containsEntry("X-Tokens-Remaining", + assertThat(exchange.getResponse().getHeaders().asMultiValueMap()).containsEntry("X-Tokens-Remaining", Collections.singletonList(tokensRemaining)); }); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactoryIntegrationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactoryIntegrationTests.java index d5951c29..235e7314 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactoryIntegrationTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactoryIntegrationTests.java @@ -43,7 +43,8 @@ class RewriteRequestParameterGatewayFilterFactoryIntegrationTests extends BaseWe .expectStatus() .isOk() .expectBody() - .jsonPath("$.args.size", "fall2023"); + .jsonPath("$.args.size") + .isEqualTo("fall2023"); } @EnableAutoConfiguration diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactoryUnitTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactoryUnitTests.java index 33de696f..7737eeb9 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactoryUnitTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactoryUnitTests.java @@ -80,9 +80,10 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = exchange.getResponse(); - assertThat(response.getHeaders()).containsOnlyKeys(X_XSS_PROTECTION_HEADER, STRICT_TRANSPORT_SECURITY_HEADER, - X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, REFERRER_POLICY_HEADER, - CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); + assertThat(response.getHeaders().headerNames()).containsOnly(X_XSS_PROTECTION_HEADER, + STRICT_TRANSPORT_SECURITY_HEADER, X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, + REFERRER_POLICY_HEADER, CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, + X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); } @Test @@ -98,9 +99,10 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = captor.getValue().getResponse(); - assertThat(response.getHeaders()).doesNotContainKeys(X_XSS_PROTECTION_HEADER, STRICT_TRANSPORT_SECURITY_HEADER, - X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, REFERRER_POLICY_HEADER, - CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); + assertThat(response.getHeaders().headerNames()).doesNotContain(X_XSS_PROTECTION_HEADER, + STRICT_TRANSPORT_SECURITY_HEADER, X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, + REFERRER_POLICY_HEADER, CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, + X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); } @@ -117,9 +119,10 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = exchange.getResponse(); - assertThat(response.getHeaders()).containsKeys(X_XSS_PROTECTION_HEADER, STRICT_TRANSPORT_SECURITY_HEADER, - X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, REFERRER_POLICY_HEADER, - CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); + assertThat(response.getHeaders().headerNames()).contains(X_XSS_PROTECTION_HEADER, + STRICT_TRANSPORT_SECURITY_HEADER, X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, + REFERRER_POLICY_HEADER, CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, + X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); assertThat(response.getHeaders().get(STRICT_TRANSPORT_SECURITY_HEADER)).containsOnly("max-age=65535"); assertThat(response.getHeaders().get(REFERRER_POLICY_HEADER)).containsOnly("referrer"); @@ -184,7 +187,7 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = captor.getValue().getResponse(); - assertThat(response.getHeaders()).doesNotContainKeys(PERMISSIONS_POLICY_HEADER); + assertThat(response.getHeaders().headerNames()).doesNotContain(PERMISSIONS_POLICY_HEADER); } @Test @@ -199,9 +202,10 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { ServerHttpResponse response = captor.getValue().getResponse(); - assertThat(response.getHeaders()).containsKeys(X_XSS_PROTECTION_HEADER, STRICT_TRANSPORT_SECURITY_HEADER, - X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, REFERRER_POLICY_HEADER, - CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); + assertThat(response.getHeaders().headerNames()).contains(X_XSS_PROTECTION_HEADER, + STRICT_TRANSPORT_SECURITY_HEADER, X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, + REFERRER_POLICY_HEADER, CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, + X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER); assertThat(response.getHeaders().get(PERMISSIONS_POLICY_HEADER)) .containsExactly(SecureHeadersProperties.PERMISSIONS_POLICY_HEADER_OPT_IN_DEFAULT); @@ -235,7 +239,7 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = captor.getValue().getResponse(); - assertThat(response.getHeaders()).containsOnlyKeys(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, + assertThat(response.getHeaders().headerNames()).containsOnly(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, PERMISSIONS_POLICY_HEADER); } @@ -255,7 +259,7 @@ public class SecureHeadersGatewayFilterFactoryUnitTests { filter.filter(exchange, filterChain).block(); ServerHttpResponse response = exchange.getResponse(); - assertThat(response.getHeaders()).containsOnlyKeys(X_XSS_PROTECTION_HEADER, X_FRAME_OPTIONS_HEADER, + assertThat(response.getHeaders().headerNames()).containsOnly(X_XSS_PROTECTION_HEADER, X_FRAME_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_HEADER, REFERRER_POLICY_HEADER, CONTENT_SECURITY_POLICY_HEADER, X_DOWNLOAD_OPTIONS_HEADER, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, PERMISSIONS_POLICY_HEADER); assertThat(response.getHeaders().get(PERMISSIONS_POLICY_HEADER)).containsExactly("camera=*"); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SetStatusGatewayFilterFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SetStatusGatewayFilterFactoryTests.java index d4db2df9..950931a3 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SetStatusGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SetStatusGatewayFilterFactoryTests.java @@ -66,7 +66,7 @@ public class SetStatusGatewayFilterFactoryTests extends BaseWebClientTests { headers.set(HttpHeaders.HOST, "www.setcustomstatus.org"); ResponseEntity response = new TestRestTemplate().exchange(baseUri + "/headers", HttpMethod.GET, new HttpEntity<>(headers), String.class); - assertThat(response.getStatusCodeValue()).isEqualTo(432); + assertThat(response.getStatusCode().value()).isEqualTo(432); // https://jira.spring.io/browse/SPR-16748 /* diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java index 76a54365..8600fcc4 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java @@ -37,6 +37,7 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -97,16 +98,17 @@ public class SpringCloudCircuitBreakerTestConfig { @RequestMapping("/resetExchangeFallbackController") public ResponseEntity> resetExchangeFallbackController(ServerWebExchange exchange) { + LinkedMultiValueMap map = exchange.getRequest() + .getHeaders() + .headerSet() + .stream() + .filter(entry -> entry.getKey().startsWith("X-Test-")) + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey() + "-fallback", entry.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, + (list1, list2) -> Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()), + LinkedMultiValueMap::new)); return ResponseEntity.status(HttpStatus.OK) - .headers((HttpHeaders) exchange.getRequest() - .getHeaders() - .entrySet() - .stream() - .filter(entry -> entry.getKey().startsWith("X-Test-")) - .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey() + "-fallback", entry.getValue())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, - (list1, list2) -> Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()), - HttpHeaders::new))) + .headers(new HttpHeaders(map)) .body(Collections.singletonMap("from", "resetExchangeFallbackController")); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactoryTests.java index 2b180a38..857c61fc 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactoryTests.java @@ -94,7 +94,7 @@ public class TokenRelayGatewayFilterFactoryTests { public void emptyPrincipal() { GatewayFilter filter = new TokenRelayGatewayFilterFactory(objectProvider).apply(); filter.filter(mockExchange, filterChain).block(TIMEOUT); - assertThat(request.getHeaders()).doesNotContainKeys(HttpHeaders.AUTHORIZATION); + assertThat(request.getHeaders().headerNames()).doesNotContain(HttpHeaders.AUTHORIZATION); } @Test @@ -125,8 +125,8 @@ public class TokenRelayGatewayFilterFactoryTests { verify(filterChain).filter(sweCaptor.capture()); ServerWebExchange mutatedServerWebExchange = sweCaptor.getValue(); - assertThat(mutatedServerWebExchange.getRequest().getHeaders()).containsEntry(HttpHeaders.AUTHORIZATION, - Collections.singletonList("Bearer mytoken")); + assertThat(mutatedServerWebExchange.getRequest().getHeaders().asMultiValueMap()) + .containsEntry(HttpHeaders.AUTHORIZATION, Collections.singletonList("Bearer mytoken")); ArgumentCaptor authorizeRequestCaptor = ArgumentCaptor .forClass(OAuth2AuthorizeRequest.class); @@ -169,8 +169,8 @@ public class TokenRelayGatewayFilterFactoryTests { verify(filterChain).filter(sweCaptor.capture()); ServerWebExchange mutatedServerWebExchange = sweCaptor.getValue(); - assertThat(mutatedServerWebExchange.getRequest().getHeaders()).containsEntry(HttpHeaders.AUTHORIZATION, - Collections.singletonList("Bearer mytoken")); + assertThat(mutatedServerWebExchange.getRequest().getHeaders().asMultiValueMap()) + .containsEntry(HttpHeaders.AUTHORIZATION, Collections.singletonList("Bearer mytoken")); ArgumentCaptor authorizeRequestCaptor = ArgumentCaptor .forClass(OAuth2AuthorizeRequest.class); @@ -191,7 +191,7 @@ public class TokenRelayGatewayFilterFactoryTests { GatewayFilter filter = new TokenRelayGatewayFilterFactory(objectProvider).apply(); filter.filter(exchange, filterChain).block(TIMEOUT); - assertThat(request.getHeaders()).doesNotContainKeys(HttpHeaders.AUTHORIZATION); + assertThat(request.getHeaders().headerNames()).doesNotContain(HttpHeaders.AUTHORIZATION); } @Test @@ -223,8 +223,8 @@ public class TokenRelayGatewayFilterFactoryTests { ArgumentCaptor sweCaptor = ArgumentCaptor.forClass(ServerWebExchange.class); verify(filterChain).filter(sweCaptor.capture()); ServerWebExchange mutatedServerWebExchange = sweCaptor.getValue(); - assertThat(mutatedServerWebExchange.getRequest().getHeaders()).containsEntry(HttpHeaders.AUTHORIZATION, - Collections.singletonList("Bearer mytoken")); + assertThat(mutatedServerWebExchange.getRequest().getHeaders().asMultiValueMap()) + .containsEntry(HttpHeaders.AUTHORIZATION, Collections.singletonList("Bearer mytoken")); ArgumentCaptor authorizeRequestCaptor = ArgumentCaptor .forClass(OAuth2AuthorizeRequest.class); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/LocalResponseCacheGatewayFilterFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/LocalResponseCacheGatewayFilterFactoryTests.java index 9c218228..b3fb9c16 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/LocalResponseCacheGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/LocalResponseCacheGatewayFilterFactoryTests.java @@ -186,7 +186,8 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header(CUSTOM_HEADER, "2") .exchange() .expectBody() - .jsonPath("$.headers." + CUSTOM_HEADER, customHeaderFromReq1)); + .jsonPath("$.headers." + CUSTOM_HEADER) + .isEqualTo(customHeaderFromReq1)); } @Test @@ -211,7 +212,8 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header("X-Request-Vary", "*") .exchange() .expectBody() - .jsonPath("$.headers." + CUSTOM_HEADER, "1"); + .jsonPath("$.headers." + CUSTOM_HEADER) + .isEqualTo("1"); testClient.get() .uri(uri) .header("Host", "www.localresponsecache.org") @@ -219,7 +221,8 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header("X-Request-Vary", "*") .exchange() .expectBody() - .jsonPath("$.headers." + CUSTOM_HEADER, "2"); + .jsonPath("$.headers." + CUSTOM_HEADER) + .isEqualTo("2"); } @Test @@ -325,7 +328,8 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header(CUSTOM_HEADER, "2") .exchange() .expectBody() - .jsonPath("$.headers." + CUSTOM_HEADER, "2"); + .jsonPath("$.headers." + CUSTOM_HEADER) + .isEqualTo("2"); } @Test @@ -348,7 +352,8 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header(CUSTOM_HEADER, "2") .exchange() .expectBody() - .jsonPath("$.headers." + CUSTOM_HEADER, "2"); + .jsonPath("$.headers." + CUSTOM_HEADER) + .isEqualTo("2"); } @Test @@ -390,7 +395,7 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .exchange() .expectBody(Map.class) .consumeWith(response -> { - assertThat(response.getResponseHeaders()).hasEntrySatisfying("Vary", + assertThat(response.getResponseHeaders().asMultiValueMap()).hasEntrySatisfying("Vary", o -> assertThat(o).contains(varyHeader)); assertThat((Map) response.getResponseBody().get("headers")).containsEntry(nonVaryHeader, expectedNonVaryResponse); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/RemoveHeaderAfterCacheExchangeMutatorTest.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/RemoveHeaderAfterCacheExchangeMutatorTest.java index 5217a779..1bbdcc2d 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/RemoveHeaderAfterCacheExchangeMutatorTest.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/RemoveHeaderAfterCacheExchangeMutatorTest.java @@ -54,7 +54,7 @@ class RemoveHeaderAfterCacheExchangeMutatorTest { mutator.accept(inputExchange, cachedResponse); - assertThat(inputExchange.getResponse().getHeaders()).doesNotContainKey(HTTP_HEADER_TO_REMOVE) + assertThat(inputExchange.getResponse().getHeaders().asMultiValueMap()).doesNotContainKey(HTTP_HEADER_TO_REMOVE) .containsEntry(CACHE_CONTROL, List.of("max-age=60")) .containsEntry(CONTENT_TYPE, List.of("application/octet-stream")) .hasSize(2); @@ -70,7 +70,7 @@ class RemoveHeaderAfterCacheExchangeMutatorTest { mutator.accept(inputExchange, cachedResponse); - assertThat(inputExchange.getResponse().getHeaders()).doesNotContainKey(HTTP_HEADER_TO_REMOVE) + assertThat(inputExchange.getResponse().getHeaders().asMultiValueMap()).doesNotContainKey(HTTP_HEADER_TO_REMOVE) .doesNotContainKey(PRAGMA) .doesNotContainKey(EXPIRES) .containsEntry(CACHE_CONTROL, List.of("max-age=60")) @@ -87,7 +87,8 @@ class RemoveHeaderAfterCacheExchangeMutatorTest { mutator.accept(inputExchange, cachedResponse); - assertThat(inputExchange.getResponse().getHeaders()).containsEntry(CACHE_CONTROL, List.of("max-age=60")) + assertThat(inputExchange.getResponse().getHeaders().asMultiValueMap()) + .containsEntry(CACHE_CONTROL, List.of("max-age=60")) .containsEntry(CONTENT_TYPE, List.of("application/octet-stream")) .hasSize(2); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/SetResponseHeadersAfterCacheExchangeMutatorTest.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/SetResponseHeadersAfterCacheExchangeMutatorTest.java index 0ec76889..cb3bf43d 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/SetResponseHeadersAfterCacheExchangeMutatorTest.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/cache/postprocessor/SetResponseHeadersAfterCacheExchangeMutatorTest.java @@ -57,7 +57,7 @@ class SetResponseHeadersAfterCacheExchangeMutatorTest { toTest.accept(inputExchange, cachedResponse); - Assertions.assertThat(inputExchange.getResponse().getHeaders()) + Assertions.assertThat(inputExchange.getResponse().getHeaders().asMultiValueMap()) .containsEntry("X-Header-1", List.of("Value-cached")); } @@ -69,7 +69,7 @@ class SetResponseHeadersAfterCacheExchangeMutatorTest { toTest.accept(inputExchange, cachedResponse); - Assertions.assertThat(inputExchange.getResponse().getHeaders()).doesNotContainKey("X-Header-1"); + Assertions.assertThat(inputExchange.getResponse().getHeaders().headerNames()).doesNotContain("X-Header-1"); } } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/ForwardedHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/ForwardedHeadersFilterTests.java index dfe83d1d..94267709 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/ForwardedHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/ForwardedHeadersFilterTests.java @@ -297,7 +297,7 @@ public class ForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).doesNotContainKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).doesNotContain(FORWARDED_HEADER); } // verify that existing forwarded header is not forwarded if not trusted @@ -313,7 +313,7 @@ public class ForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).contains(FORWARDED_HEADER); List forwardedHeaders = headers.get(FORWARDED_HEADER); Optional filtered = forwardedHeaders.stream().filter(value -> value.contains("127.0.0.1")).findFirst(); assertThat(filtered).isEmpty(); @@ -332,7 +332,7 @@ public class ForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(FORWARDED_HEADER); + assertThat(headers.headerNames()).contains(FORWARDED_HEADER); List forwardedHeaders = headers.get(FORWARDED_HEADER); Optional filtered = forwardedHeaders.stream().filter(value -> value.contains("127.0.0.1")).findFirst(); assertThat(filtered).isEmpty(); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/GRPCRequestHeadersFilterTest.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/GRPCRequestHeadersFilterTest.java index ea23db6b..12d43d2c 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/GRPCRequestHeadersFilterTest.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/GRPCRequestHeadersFilterTest.java @@ -39,7 +39,7 @@ public class GRPCRequestHeadersFilterTest { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys("te"); + assertThat(headers.headerNames()).contains("te"); assertThat(headers.getFirst("te")).isEqualTo("trailers"); } @@ -54,7 +54,7 @@ public class GRPCRequestHeadersFilterTest { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).doesNotContainKeys("te"); + assertThat(headers.headerNames()).doesNotContain("te"); } } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterMixedTypeTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterMixedTypeTests.java index cbb9a4d2..e452dcfb 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterMixedTypeTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterMixedTypeTests.java @@ -50,7 +50,7 @@ public class HttpHeadersFilterMixedTypeTests { HttpHeaders result = HttpHeadersFilter.filterRequest(Arrays.asList(filter1, filter2), MockServerWebExchange.from(mockRequest)); - assertThat(result).containsOnlyKeys("header1", "header3"); + assertThat(result.headerNames()).containsOnly("header1", "header3"); } private HttpHeadersFilter filterRemovingHeaders(Type type, String... headerNames) { diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterTests.java index 9619b71f..6f5df881 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/HttpHeadersFilterTests.java @@ -46,7 +46,7 @@ public class HttpHeadersFilterTests { HttpHeaders headers = HttpHeadersFilter.filterRequest(filters, MockServerWebExchange.from(request)); - assertThat(headers).containsOnlyKeys("X-C"); + assertThat(headers.headerNames()).containsOnly("X-C"); } private HttpHeaders filter(HttpHeaders input, String keyToFilter) { diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/RemoveHopByHopHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/RemoveHopByHopHeadersFilterTests.java index 689821f6..ae6c2df8 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/RemoveHopByHopHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/RemoveHopByHopHeadersFilterTests.java @@ -98,7 +98,7 @@ public class RemoveHopByHopHeadersFilterTests { Set toRemove = new HashSet<>(HEADERS_REMOVED_ON_REQUEST); toRemove.addAll(Arrays.asList(additionalHeaders)); - assertThat(headers).doesNotContainKeys(toRemove.toArray(new String[0])); + assertThat(headers.headerNames()).doesNotContain(toRemove.toArray(new String[0])); } } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilterTests.java index 68e223a0..40956593 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilterTests.java @@ -35,7 +35,8 @@ public class TransferEncodingNormalizationHeadersFilterTests { .header(HttpHeaders.CONTENT_LENGTH, "6"); HttpHeaders headers = testFilter(MockServerWebExchange.from(builder)); - assertThat(headers).containsKey(HttpHeaders.CONTENT_LENGTH).doesNotContainKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).contains(HttpHeaders.CONTENT_LENGTH) + .doesNotContain(HttpHeaders.TRANSFER_ENCODING); } @Test @@ -45,7 +46,8 @@ public class TransferEncodingNormalizationHeadersFilterTests { .header(HttpHeaders.TRANSFER_ENCODING, "chunked"); HttpHeaders headers = testFilter(MockServerWebExchange.from(builder)); - assertThat(headers).doesNotContainKey(HttpHeaders.CONTENT_LENGTH).containsKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).doesNotContain(HttpHeaders.CONTENT_LENGTH) + .contains(HttpHeaders.TRANSFER_ENCODING); } @Test @@ -55,7 +57,8 @@ public class TransferEncodingNormalizationHeadersFilterTests { .header(HttpHeaders.TRANSFER_ENCODING, "Chunked "); HttpHeaders headers = testFilter(MockServerWebExchange.from(builder)); - assertThat(headers).doesNotContainKey(HttpHeaders.CONTENT_LENGTH).containsKey(HttpHeaders.TRANSFER_ENCODING); + assertThat(headers.headerNames()).doesNotContain(HttpHeaders.CONTENT_LENGTH) + .contains(HttpHeaders.TRANSFER_ENCODING); } private HttpHeaders testFilter(MockServerWebExchange exchange) { diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java index f6918803..6cb473be 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java @@ -63,8 +63,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).doesNotContainKeys(X_FORWARDED_FOR_HEADER) - .containsKeys(X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).doesNotContain(X_FORWARDED_FOR_HEADER) + .contains(X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("localhost:8080"); assertThat(headers.getFirst(X_FORWARDED_PORT_HEADER)).isEqualTo("8080"); @@ -82,8 +82,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).isEqualTo("10.0.0.1"); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("localhost:8080"); @@ -102,8 +102,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).isEqualTo("10.0.0.1"); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("localhost"); @@ -125,8 +125,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).isEqualTo("192.168.0.2,10.0.0.1"); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("example.com,localhost:8080"); @@ -154,8 +154,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER, X_FORWARDED_PREFIX_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER, X_FORWARDED_PREFIX_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).isEqualTo("10.0.0.1"); assertThat(headers.getFirst(X_FORWARDED_HOST_HEADER)).isEqualTo("localhost:8080"); @@ -184,7 +184,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), exchange); - assertThat(headers).containsKeys(X_FORWARDED_PREFIX_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_PREFIX_HEADER); assertThat(headers.getFirst(X_FORWARDED_PREFIX_HEADER)).isEqualTo("/prefix"); } @@ -210,7 +210,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), exchange); - assertThat(headers).containsKeys(X_FORWARDED_PREFIX_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_PREFIX_HEADER); assertThat(headers.getFirst(X_FORWARDED_PREFIX_HEADER)).isEqualTo("/resource"); } @@ -260,7 +260,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), exchange); - assertThat(headers).isEmpty(); + assertThat(headers.isEmpty()).isTrue(); } @Test @@ -286,7 +286,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), exchange); - assertThat(headers).isEmpty(); + assertThat(headers.isEmpty()).isTrue(); } @Test @@ -304,7 +304,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).isEmpty(); + assertThat(headers.isEmpty()).isTrue(); } @Test @@ -318,7 +318,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).isEqualTo("10.0.0.1,10.0.0.1"); } @@ -334,7 +334,7 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).doesNotContainKeys(X_FORWARDED_PROTO_HEADER, X_FORWARDED_HOST_HEADER); + assertThat(headers.headerNames()).doesNotContain(X_FORWARDED_PROTO_HEADER, X_FORWARDED_HOST_HEADER); } @Test @@ -375,8 +375,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).doesNotContainKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).doesNotContain(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); } // : verify that existing x-forwarded-* headers are not forwarded @@ -394,8 +394,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).doesNotContain("127.0.0.1") .contains("10.0.0.1", "10.0.0.10"); @@ -412,8 +412,8 @@ public class XForwardedHeadersFilterTests { HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request)); - assertThat(headers).containsKeys(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, X_FORWARDED_PORT_HEADER, - X_FORWARDED_PROTO_HEADER); + assertThat(headers.headerNames()).contains(X_FORWARDED_FOR_HEADER, X_FORWARDED_HOST_HEADER, + X_FORWARDED_PORT_HEADER, X_FORWARDED_PROTO_HEADER); assertThat(headers.getFirst(X_FORWARDED_FOR_HEADER)).doesNotContain("127.0.0.1"); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java index bdd1fcd6..21d48176 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java @@ -111,7 +111,8 @@ class B3BraveObservedHttpHeadersFilterTests { headers = responseHttpHeadersFilter.filter(headers, exchange); // then - assertThat(headers).containsOnlyKeys("X-A", "b3").doesNotContainEntry("b3", request.getHeaders().get("b3")); + assertThat(headers.asMultiValueMap()).containsOnlyKeys("X-A", "b3") + .doesNotContainEntry("b3", request.getHeaders().get("b3")); assertThat(headers.get("b3").get(0)).matches("^" + context.traceId() + "-(.*)-1-" + context.spanId() + "$"); List finishedSpans = testSpanHandler.spans() .stream() diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayPropagatingSenderTracingObservationHandlerTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayPropagatingSenderTracingObservationHandlerTests.java index 6187080f..4f23ede7 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayPropagatingSenderTracingObservationHandlerTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayPropagatingSenderTracingObservationHandlerTests.java @@ -70,7 +70,7 @@ class GatewayPropagatingSenderTracingObservationHandlerTests { handler.onStart(gatewayContext); - then(headers).doesNotContainKeys("foo", "bar") + then(headers.asMultiValueMap()).doesNotContainKeys("foo", "bar") .containsEntry("baz", Collections.singletonList("baz value")) .containsEntry("remote", Collections.singletonList("remote value")); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java index 9b223964..d3a2e399 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java @@ -86,7 +86,7 @@ public class ObservedHttpHeadersFilterTests extends SampleTestRunner { // then assertThat((String) exchange.getAttribute(ObservedResponseHttpHeadersFilter.OBSERVATION_STOPPED)) .isNotNull(); - assertThat(headers).containsEntry("X-A", Collections.singletonList("aValue")) + assertThat(headers.asMultiValueMap()).containsEntry("X-A", Collections.singletonList("aValue")) .containsEntry("X-B3-Sampled", Collections.singletonList("1")) .containsEntry("X-B3-TraceId", Collections.singletonList(context.traceId())) .doesNotContainEntry("X-B3-SpanId", Collections.singletonList(context.spanId())) diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtilsTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtilsTests.java index a4f818c0..6911375c 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtilsTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtilsTests.java @@ -119,9 +119,9 @@ public class ServerWebExchangeUtilsTests { .as("exchange attributes") .doesNotContainKey(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR); - Assertions.assertThat(exchange.getRequest().getHeaders()) + Assertions.assertThat(exchange.getRequest().getHeaders().headerNames()) .as("request headers") - .doesNotContainKey(HttpHeaders.ORIGIN); + .doesNotContain(HttpHeaders.ORIGIN); })); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpBinCompatibleController.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpBinCompatibleController.java index 5872965f..e4f73729 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpBinCompatibleController.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpBinCompatibleController.java @@ -44,6 +44,7 @@ import org.springframework.http.codec.multipart.FilePart; import org.springframework.http.codec.multipart.Part; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.FileCopyUtils; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; @@ -175,14 +176,15 @@ public class HttpBinCompatibleController { @RequestMapping(value = "/responseheaders/{status}", method = { RequestMethod.GET, RequestMethod.POST }) public ResponseEntity> responseHeaders(@PathVariable int status, ServerWebExchange exchange) { - HttpHeaders httpHeaders = exchange.getRequest() + LinkedMultiValueMap map = exchange.getRequest() .getHeaders() .headerSet() .stream() .filter(entry -> entry.getKey().startsWith("X-Test-")) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (list1, list2) -> Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()), - HttpHeaders::new)); + LinkedMultiValueMap::new)); + HttpHeaders httpHeaders = new HttpHeaders(map); return ResponseEntity.status(status).headers(httpHeaders).body(Collections.singletonMap("status", status)); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpStatusTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpStatusTests.java index f011fe85..0d9e30b4 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpStatusTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/HttpStatusTests.java @@ -58,7 +58,7 @@ public class HttpStatusTests extends BaseWebClientTests { @Test void nonStandardCodeWorks() { ResponseEntity response = new TestRestTemplate().getForEntity(baseUri + "/status/432", String.class); - assertThat(response.getStatusCodeValue()).isEqualTo(432); + assertThat(response.getStatusCode().value()).isEqualTo(432); assertThat(response.getBody()).isEqualTo("Failed with 432"); /* diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java index 7de7b5d9..568ab1a5 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java @@ -366,7 +366,7 @@ public class WebSocketIntegrationTests { @Override public Mono handle(WebSocketSession session) { HttpHeaders headers = session.getHandshakeInfo().getHeaders(); - if (!headers.containsKey("my-header")) { + if (!headers.containsHeader("my-header")) { return Mono.error(new IllegalStateException("Missing my-header")); } String payload = "my-header:" + headers.getFirst("my-header"); diff --git a/spring-cloud-gateway-webflux/pom.xml b/spring-cloud-gateway-webflux/pom.xml index b9fbcffb..f5dc197b 100644 --- a/spring-cloud-gateway-webflux/pom.xml +++ b/spring-cloud-gateway-webflux/pom.xml @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. diff --git a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java index 47dfb962..c4ef97cf 100644 --- a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java +++ b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java @@ -400,13 +400,13 @@ public class ProxyExchange { private void addHeaders(HttpHeaders headers, HttpHeaders toAdd) { Set filteredKeys = filterHeaderKeys(toAdd); filteredKeys.stream() - .filter(key -> !headers.containsKey(key)) + .filter(key -> !headers.containsHeader(key)) .forEach(header -> headers.addAll(header, toAdd.get(header))); } private Set filterHeaderKeys(HttpHeaders headers) { final Set excludedHeaders = this.excluded != null ? this.excluded : Collections.emptySet(); - return headers.keySet() + return headers.headerNames() .stream() .filter(header -> !excludedHeaders.contains(header.toLowerCase(Locale.ROOT))) .collect(Collectors.toSet()); 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 732f71f8..8522309f 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 @@ -479,7 +479,7 @@ public class ProductionConfigurationTests { @GetMapping("/headers") public Map> headers(@RequestHeader HttpHeaders headers) { - return headers; + return headers.asMultiValueMap(); } @DeleteMapping("/foos/{id}/no-body") diff --git a/spring-cloud-starter-gateway-mvc/pom.xml b/spring-cloud-starter-gateway-mvc/pom.xml index 66b92a2d..2af4b211 100644 --- a/spring-cloud-starter-gateway-mvc/pom.xml +++ b/spring-cloud-starter-gateway-mvc/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-starter-gateway-mvc diff --git a/spring-cloud-starter-gateway-server-webflux/pom.xml b/spring-cloud-starter-gateway-server-webflux/pom.xml index da44d2f6..afe2b234 100644 --- a/spring-cloud-starter-gateway-server-webflux/pom.xml +++ b/spring-cloud-starter-gateway-server-webflux/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-starter-gateway-server-webflux diff --git a/spring-cloud-starter-gateway-server-webmvc/pom.xml b/spring-cloud-starter-gateway-server-webmvc/pom.xml index e76833ed..893f3957 100644 --- a/spring-cloud-starter-gateway-server-webmvc/pom.xml +++ b/spring-cloud-starter-gateway-server-webmvc/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-starter-gateway-server-webmvc diff --git a/spring-cloud-starter-gateway/pom.xml b/spring-cloud-starter-gateway/pom.xml index de0fee0a..202899c0 100644 --- a/spring-cloud-starter-gateway/pom.xml +++ b/spring-cloud-starter-gateway/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-gateway - 4.3.1-SNAPSHOT + 5.0.0-SNAPSHOT .. spring-cloud-starter-gateway