From 28166054c4e6c16d8eb24874315b72ef5b50d85f Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 19 Jun 2018 22:05:43 -0400 Subject: [PATCH] Only sets content type attr if not null. fixes gh-374 --- .../gateway/filter/NettyRoutingFilter.java | 5 ++++- .../gateway/support/ServerWebExchangeUtils.java | 1 + .../gateway/test/GatewayIntegrationTests.java | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java index af860479..ab36e983 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java @@ -42,6 +42,7 @@ import org.springframework.web.server.ServerWebExchange; import static org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter.filterRequest; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setAlreadyRouted; @@ -114,7 +115,9 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered { res.responseHeaders().forEach(entry -> headers.add(entry.getKey(), entry.getValue())); - exchange.getAttributes().put("original_response_content_type", headers.getContentType()); + if (headers.getContentType() != null) { + exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR, headers.getContentType()); + } HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter( this.headersFilters.getIfAvailable(), headers, exchange, Type.RESPONSE); diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java index 69a67f42..7269fa6b 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java @@ -48,6 +48,7 @@ public class ServerWebExchangeUtils { public static final String GATEWAY_SCHEME_PREFIX_ATTR = qualify("gatewaySchemePrefix"); public static final String GATEWAY_PREDICATE_ROUTE_ATTR = qualify("gatewayPredicateRouteAttr"); public static final String WEIGHT_ATTR = qualify("routeWeight"); + public static final String ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR = "original_response_content_type"; /** * Used when a routing filter has been successfully call. Allows users to write custom diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java index 64591857..5cdffdf7 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java @@ -39,8 +39,11 @@ import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; @@ -146,13 +149,27 @@ public class GatewayIntegrationTests extends BaseWebClientTests { .expectStatus().is5xxServerError(); } + @Test + // gh-374 no content type/empty body causes NPR in NettyRoutingFilter + public void noContentType() { + testClient.get().uri("/nocontenttype") + .exchange() + .expectStatus().is2xxSuccessful(); + } + @EnableAutoConfiguration @SpringBootConfiguration @Import(DefaultTestConfig.class) + @RestController public static class TestConfig { private static final Log log = LogFactory.getLog(TestConfig.class); + @RequestMapping("/httpbin/nocontenttype") + public ResponseEntity nocontenttype() { + return ResponseEntity.status(204).build(); + } + @Bean @Order(-1) public GlobalFilter postFilter() {