fix post request with body processed twice in retry filter https://github.com/spring-cloud/spring-cloud-gateway/issues/1315
This commit is contained in:
committed by
Spencer Gibb
parent
0d2b87af30
commit
e285b841de
@@ -70,11 +70,18 @@ public class AdaptCachedBodyGlobalFilter
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
final Mono<String> requestProcessingFinishedFlag = Mono
|
||||
.just("requestProcessingFinishedFlag");
|
||||
return ServerWebExchangeUtils
|
||||
.cacheRequestBody(exchange,
|
||||
(serverHttpRequest) -> chain.filter(
|
||||
exchange.mutate().request(serverHttpRequest).build()))
|
||||
.switchIfEmpty(chain.filter(exchange));
|
||||
.cacheRequestBody(exchange, (serverHttpRequest) -> chain
|
||||
.filter(exchange.mutate().request(serverHttpRequest).build())
|
||||
// suppress empty mono response from FilteringWebHandler, see
|
||||
// https://github.com/spring-cloud/spring-cloud-gateway/issues/1315
|
||||
.then(requestProcessingFinishedFlag))
|
||||
// when request body is empty - we return from cacheRequestBody() with
|
||||
// empty mono - so we will process that request
|
||||
.switchIfEmpty(chain.filter(exchange).then(requestProcessingFinishedFlag))
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,8 @@ import com.netflix.loadbalancer.ServerList;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -34,6 +36,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.rule.OutputCapture;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory.RetryConfig;
|
||||
@@ -49,6 +52,7 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -63,8 +67,20 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
"spring.cloud.gateway.httpclient.connect-timeout=500",
|
||||
"spring.cloud.gateway.httpclient.response-timeout=2s" })
|
||||
@DirtiesContext
|
||||
// default filter AddResponseHeader suppresses bug
|
||||
// https://github.com/spring-cloud/spring-cloud-gateway/issues/1315,
|
||||
// so we use only PrefixPath filter
|
||||
@ActiveProfiles("only-prefix-filter")
|
||||
public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTests {
|
||||
|
||||
@Rule
|
||||
public final OutputCapture capture = new OutputCapture();
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
capture.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFilterGet() {
|
||||
testClient.get().uri("/retry?key=get").exchange().expectStatus().isOk()
|
||||
@@ -115,6 +131,17 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
|
||||
.exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFilterPostOneTime() {
|
||||
testClient.post().uri(
|
||||
"/retrypost?key=retryFilterPostOneTime&expectedbody=HelloGateway&count=1")
|
||||
.header(HttpHeaders.HOST, "www.retrypostconfig.org")
|
||||
.syncBody("HelloGateway").exchange().expectStatus().isOk();
|
||||
assertThat(this.capture.toString()).contains("setting new iteration in attr 0");
|
||||
assertThat(this.capture.toString())
|
||||
.doesNotContain("setting new iteration in attr 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retriesSleepyRequest() throws Exception {
|
||||
testClient.mutate().responseTimeout(Duration.ofSeconds(10)).build().get()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
default-filters:
|
||||
- PrefixPath=/httpbin
|
||||
Reference in New Issue
Block a user