Browse Source

Adds support for spring.codec.* in modify request body filter.

Also adds test for support added in modify response.

Fixes gh-1596
pull/1613/head
Spencer Gibb 5 years ago
parent
commit
3d2be39670
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 9
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
  2. 8
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactory.java
  3. 33
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java
  4. 23
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactoryTests.java
  5. 35
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactoryTests.java
  6. 3
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactoryUnitTests.java

9
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@ -434,8 +434,9 @@ public class GatewayAutoConfiguration { @@ -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 { @@ -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

8
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactory.java

@ -53,9 +53,15 @@ public class ModifyRequestBodyGatewayFilterFactory extends @@ -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

33
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java

@ -41,6 +41,7 @@ import org.springframework.http.HttpHeaders; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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();
}

23
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactoryTests.java

@ -42,7 +42,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @@ -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 @@ -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 @@ -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();
}

35
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactoryTests.java

@ -33,18 +33,32 @@ import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; @@ -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 @@ -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 @@ -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();
}

3
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactoryUnitTests.java

@ -34,7 +34,8 @@ public class ModifyResponseBodyGatewayFilterFactoryUnitTests { @@ -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");
}

Loading…
Cancel
Save