diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/RemoveCachedBodyFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/RemoveCachedBodyFilter.java index 5307cb98..e3b15fe8 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/RemoveCachedBodyFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/RemoveCachedBodyFilter.java @@ -16,37 +16,17 @@ package org.springframework.cloud.gateway.filter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; import org.springframework.core.Ordered; -import org.springframework.core.io.buffer.PooledDataBuffer; import org.springframework.web.server.ServerWebExchange; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR; - public class RemoveCachedBodyFilter implements GlobalFilter, Ordered { - private static final Log log = LogFactory.getLog(RemoveCachedBodyFilter.class); - @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - return chain.filter(exchange).doFinally(s -> { - Object attribute = exchange.getAttributes().remove(CACHED_REQUEST_BODY_ATTR); - if (attribute != null && attribute instanceof PooledDataBuffer) { - PooledDataBuffer dataBuffer = (PooledDataBuffer) attribute; - if (dataBuffer.isAllocated()) { - if (log.isTraceEnabled()) { - log.trace("releasing cached body in exchange attribute"); - } - // ensure proper release - while (!dataBuffer.release()) { - // release() counts down until zero, will never be infinite loop - } - } - } - }); + return chain.filter(exchange).doFinally(s -> ServerWebExchangeUtils.clearCachedRequestBody(exchange)); } @Override diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java index fb12f36b..eb0006a8 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java @@ -24,6 +24,7 @@ import org.springframework.cloud.gateway.config.GatewayProperties; import org.springframework.cloud.gateway.config.GlobalCorsProperties; import org.springframework.cloud.gateway.route.Route; import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; import org.springframework.core.env.Environment; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.handler.AbstractHandlerMapping; @@ -99,6 +100,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { }) .switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> { exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR); + ServerWebExchangeUtils.clearCachedRequestBody(exchange); if (logger.isTraceEnabled()) { logger.trace("No RouteDefinition found for [" + getExchangeDesc(exchange) + "]"); } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java index 0ce96e64..36ee17d9 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java @@ -40,6 +40,7 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBuffer; import org.springframework.core.io.buffer.NettyDataBuffer; +import org.springframework.core.io.buffer.PooledDataBuffer; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.AbstractServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpRequest; @@ -379,6 +380,27 @@ public final class ServerWebExchangeUtils { .flatMap(function); } + /** + * clear the request body in a ServerWebExchange attribute. The attribute is + * {@link #CACHED_REQUEST_BODY_ATTR}. + * @param exchange the available ServerWebExchange. + */ + public static void clearCachedRequestBody(ServerWebExchange exchange) { + Object attribute = exchange.getAttributes().remove(CACHED_REQUEST_BODY_ATTR); + if (attribute != null && attribute instanceof PooledDataBuffer) { + PooledDataBuffer dataBuffer = (PooledDataBuffer) attribute; + if (dataBuffer.isAllocated()) { + if (log.isTraceEnabled()) { + log.trace("releasing cached body in exchange attribute"); + } + // ensure proper release + while (!dataBuffer.release()) { + // release() counts down until zero, will never be infinite loop + } + } + } + } + private static ServerHttpRequest decorate(ServerWebExchange exchange, DataBuffer dataBuffer, boolean cacheDecoratedRequest) { if (dataBuffer.readableByteCount() > 0) {