Adds support for spring.codec.* in modify request body filter.
Also adds test for support added in modify response. Fixes gh-1596
This commit is contained in:
@@ -434,8 +434,9 @@ public class GatewayAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory() {
|
||||
return new ModifyRequestBodyGatewayFilterFactory();
|
||||
public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory(
|
||||
ServerCodecConfigurer codecConfigurer) {
|
||||
return new ModifyRequestBodyGatewayFilterFactory(codecConfigurer.getReaders());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -447,8 +448,8 @@ public class GatewayAutoConfiguration {
|
||||
public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(
|
||||
ServerCodecConfigurer codecConfigurer, Set<MessageBodyDecoder> bodyDecoders,
|
||||
Set<MessageBodyEncoder> bodyEncoders) {
|
||||
return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer, bodyDecoders,
|
||||
bodyEncoders);
|
||||
return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer.getReaders(),
|
||||
bodyDecoders, bodyEncoders);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -53,9 +53,15 @@ public class ModifyRequestBodyGatewayFilterFactory extends
|
||||
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
|
||||
}
|
||||
|
||||
public ModifyRequestBodyGatewayFilterFactory(
|
||||
List<HttpMessageReader<?>> messageReaders) {
|
||||
super(Config.class);
|
||||
this.messageReaders = messageReaders;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ModifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
|
||||
this();
|
||||
this(codecConfigurer.getReaders());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.http.client.reactive.ClientHttpResponse;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
|
||||
@@ -49,6 +50,7 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.BodyInserter;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.server.HandlerStrategies;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static java.util.function.Function.identity;
|
||||
@@ -61,17 +63,16 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.O
|
||||
public class ModifyResponseBodyGatewayFilterFactory extends
|
||||
AbstractGatewayFilterFactory<ModifyResponseBodyGatewayFilterFactory.Config> {
|
||||
|
||||
@Nullable
|
||||
private final ServerCodecConfigurer codecConfigurer;
|
||||
|
||||
private final Map<String, MessageBodyDecoder> messageBodyDecoders;
|
||||
|
||||
private final Map<String, MessageBodyEncoder> messageBodyEncoders;
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders;
|
||||
|
||||
@Deprecated
|
||||
public ModifyResponseBodyGatewayFilterFactory() {
|
||||
super(Config.class);
|
||||
this.codecConfigurer = null;
|
||||
messageReaders = HandlerStrategies.withDefaults().messageReaders();
|
||||
messageBodyDecoders = Collections.emptyMap();
|
||||
messageBodyEncoders = Collections.emptyMap();
|
||||
}
|
||||
@@ -79,16 +80,17 @@ public class ModifyResponseBodyGatewayFilterFactory extends
|
||||
@Deprecated
|
||||
public ModifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
|
||||
super(Config.class);
|
||||
this.codecConfigurer = codecConfigurer;
|
||||
this.messageReaders = codecConfigurer.getReaders();
|
||||
messageBodyDecoders = Collections.emptyMap();
|
||||
messageBodyEncoders = Collections.emptyMap();
|
||||
}
|
||||
|
||||
public ModifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer,
|
||||
public ModifyResponseBodyGatewayFilterFactory(
|
||||
List<HttpMessageReader<?>> messageReaders,
|
||||
Set<MessageBodyDecoder> messageBodyDecoders,
|
||||
Set<MessageBodyEncoder> messageBodyEncoders) {
|
||||
super(Config.class);
|
||||
this.codecConfigurer = codecConfigurer;
|
||||
this.messageReaders = messageReaders;
|
||||
this.messageBodyDecoders = messageBodyDecoders.stream()
|
||||
.collect(Collectors.toMap(MessageBodyDecoder::encodingType, identity()));
|
||||
this.messageBodyEncoders = messageBodyEncoders.stream()
|
||||
@@ -98,7 +100,7 @@ public class ModifyResponseBodyGatewayFilterFactory extends
|
||||
@Override
|
||||
public GatewayFilter apply(Config config) {
|
||||
ModifyResponseGatewayFilter gatewayFilter = new ModifyResponseGatewayFilter(
|
||||
config, codecConfigurer);
|
||||
config);
|
||||
gatewayFilter.setFactory(this);
|
||||
return gatewayFilter;
|
||||
}
|
||||
@@ -185,20 +187,16 @@ public class ModifyResponseBodyGatewayFilterFactory extends
|
||||
|
||||
private final Config config;
|
||||
|
||||
@Nullable
|
||||
private final ServerCodecConfigurer codecConfigurer;
|
||||
|
||||
private GatewayFilterFactory<Config> gatewayFilterFactory;
|
||||
|
||||
@Deprecated
|
||||
public ModifyResponseGatewayFilter(Config config) {
|
||||
this(config, null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ModifyResponseGatewayFilter(Config config,
|
||||
@Nullable ServerCodecConfigurer codecConfigurer) {
|
||||
this.config = config;
|
||||
this.codecConfigurer = codecConfigurer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -299,13 +297,8 @@ public class ModifyResponseBodyGatewayFilterFactory extends
|
||||
private ClientResponse prepareClientResponse(Publisher<? extends DataBuffer> body,
|
||||
HttpHeaders httpHeaders) {
|
||||
ClientResponse.Builder builder;
|
||||
if (codecConfigurer != null) {
|
||||
builder = ClientResponse.create(exchange.getResponse().getStatusCode(),
|
||||
codecConfigurer.getReaders());
|
||||
}
|
||||
else {
|
||||
builder = ClientResponse.create(exchange.getResponse().getStatusCode());
|
||||
}
|
||||
builder = ClientResponse.create(exchange.getResponse().getStatusCode(),
|
||||
messageReaders);
|
||||
return builder.headers(headers -> headers.putAll(httpHeaders))
|
||||
.body(Flux.from(body)).build();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
* @author Junghoon Song
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT,
|
||||
properties = "spring.codec.max-in-memory-size=13")
|
||||
@DirtiesContext
|
||||
public class ModifyRequestBodyGatewayFilterFactoryTests extends BaseWebClientTests {
|
||||
|
||||
@@ -66,6 +67,17 @@ public class ModifyRequestBodyGatewayFilterFactoryTests extends BaseWebClientTes
|
||||
.isEqualTo("modifyrequest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyRequestBodyToLarge() {
|
||||
testClient.post().uri("/post")
|
||||
.header("Host", "www.modifyrequestbodyemptytolarge.org")
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
|
||||
.body(BodyInserters.fromValue("request")).exchange().expectStatus()
|
||||
.isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectBody()
|
||||
.jsonPath("message")
|
||||
.isEqualTo("Exceeded limit on max bytes to buffer : 13");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
@Import(DefaultTestConfig.class)
|
||||
@@ -95,6 +107,15 @@ public class ModifyRequestBodyGatewayFilterFactoryTests extends BaseWebClientTes
|
||||
return Mono.just(body.toUpperCase());
|
||||
}))
|
||||
.uri(uri))
|
||||
.route("test_modify_request_body_to_large", r -> r.order(-1)
|
||||
.host("**.modifyrequestbodyemptytolarge.org")
|
||||
.filters(f -> f.modifyRequestBody(String.class, String.class,
|
||||
MediaType.APPLICATION_JSON_VALUE,
|
||||
(serverWebExchange, body) -> {
|
||||
return Mono.just(
|
||||
"tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge-tolarge");
|
||||
}))
|
||||
.uri(uri))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,18 +33,32 @@ import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||||
import org.springframework.cloud.gateway.test.BaseWebClientTests;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT,
|
||||
properties = "spring.codec.max-in-memory-size=40")
|
||||
@DirtiesContext
|
||||
public class ModifyResponseBodyGatewayFilterFactoryTests extends BaseWebClientTests {
|
||||
|
||||
private static final String toLarge;
|
||||
|
||||
static {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
sb.append("to-large-");
|
||||
}
|
||||
toLarge = sb.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModificationOfResponseBody() {
|
||||
URI uri = UriComponentsBuilder.fromUriString(this.baseUri + "/").build(true)
|
||||
@@ -55,6 +69,17 @@ public class ModifyResponseBodyGatewayFilterFactoryTests extends BaseWebClientTe
|
||||
.json("{\"value\": \"httpbin compatible home\", \"length\": 23}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResponeBodyToLarge() {
|
||||
testClient.post().uri("/post")
|
||||
.header("Host", "www.modifyresponsebodyjavatoolarge.org")
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.body(BodyInserters.fromValue(toLarge)).exchange().expectStatus()
|
||||
.isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectBody()
|
||||
.jsonPath("message")
|
||||
.isEqualTo("Exceeded limit on max bytes to buffer : 40");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
@Import(DefaultTestConfig.class)
|
||||
@@ -77,6 +102,14 @@ public class ModifyResponseBodyGatewayFilterFactoryTests extends BaseWebClientTe
|
||||
return Mono.just(modifiedResponse);
|
||||
}))
|
||||
.uri(uri))
|
||||
.route("modify_response_java_test_to_large",
|
||||
r -> r.path("/").and().host("www.modifyresponsebodyjavatoolarge.org")
|
||||
.filters(f -> f.prefixPath("/httpbin").modifyResponseBody(
|
||||
String.class, String.class,
|
||||
(webExchange, originalResponse) -> {
|
||||
return Mono.just(toLarge);
|
||||
}))
|
||||
.uri(uri))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ public class ModifyResponseBodyGatewayFilterFactoryUnitTests {
|
||||
config.setOutClass(Integer.class);
|
||||
config.setNewContentType("mycontenttype");
|
||||
GatewayFilter filter = new ModifyResponseBodyGatewayFilterFactory(
|
||||
new DefaultServerCodecConfigurer(), emptySet(), emptySet()).apply(config);
|
||||
new DefaultServerCodecConfigurer().getReaders(), emptySet(), emptySet())
|
||||
.apply(config);
|
||||
assertThat(filter.toString()).contains("String").contains("Integer")
|
||||
.contains("mycontenttype");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user