From f1ea09ae3e2e6c2d7b328164d864802259a4f31d Mon Sep 17 00:00:00 2001 From: Ignacio Lozano Date: Mon, 24 Apr 2023 19:16:02 +0200 Subject: [PATCH] Fix bug when combining LocalResponseCache (#2930) Using ```yml - StripPrefix=0 - LocalResponseCache=3m,1MB - RemoveJsonAttributesResponseBody=args,data,files,Sec-Fetch-Dest,true uri: https://httpbin.org ``` the Flux was replaced by other type, provoking a ClassCastException --- .../cache/ResponseCacheGatewayFilter.java | 5 ++--- ...lResponseCacheGatewayFilterFactoryTests.java | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/cache/ResponseCacheGatewayFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/cache/ResponseCacheGatewayFilter.java index 65ed57b7..a7769df1 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/cache/ResponseCacheGatewayFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/cache/ResponseCacheGatewayFilter.java @@ -95,11 +95,10 @@ public class ResponseCacheGatewayFilter implements GatewayFilter, Ordered { Flux decoratedBody; if (responseCacheManager.isResponseCacheable(response)) { - decoratedBody = responseCacheManager.processFromUpstream(metadataKey, exchange, - (Flux) body); + decoratedBody = responseCacheManager.processFromUpstream(metadataKey, exchange, Flux.from(body)); } else { - decoratedBody = (Flux) body; + decoratedBody = Flux.from(body); } return super.writeWith(decoratedBody); 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 83dec72f..f7e06e07 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 @@ -207,6 +207,16 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe .header(CUSTOM_HEADER, "2").exchange().expectBody().jsonPath("$.headers." + CUSTOM_HEADER, "2"); } + @Test + void shouldWorkInCombinationWithRemoveJsonAttributes() { + String uri = "/" + UUID.randomUUID() + "/cache-and-remove-jsonattrs/headers"; + + testClient.method(HttpMethod.GET).uri(uri).header("Host", "www.localresponsecache.org") + .exchange().expectBody(String.class).consumeWith(body -> { + assertThat(body.getResponseBody()).doesNotContain("headers"); + }); + } + private Long parseMaxAge(String cacheControlValue) { if (StringUtils.hasText(cacheControlValue)) { Pattern maxAgePattern = Pattern.compile("\\bmax-age=(\\d+)\\b"); @@ -241,6 +251,13 @@ public class LocalResponseCacheGatewayFilterFactoryTests extends BaseWebClientTe @Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes() + .route("local_response_cache_combined_remove_json_attrs", + r -> r.path("/{namespace}/cache-and-remove-jsonattrs/**").and().host("{sub}.localresponsecache.org") + .filters(f -> f.stripPrefix(2).prefixPath("/httpbin") + .localResponseCache(Duration.ofMinutes(2), null) + .removeJsonAttributes("headers") + ) + .uri(uri)) .route("local_response_cache_java_test", r -> r.path("/{namespace}/cache/**").and().host("{sub}.localresponsecache.org") .filters(f -> f.stripPrefix(2).prefixPath("/httpbin")