From 9322f05945164f2cd6e928a2634214db65490720 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 15 Mar 2017 00:28:23 -0600 Subject: [PATCH] Moves PublicDefaultServerRequest to proper package. --- .../RequestPredicateHandlerMapping.java | 5 +- .../CookieRequestPredicateFactory.java | 6 +- .../QueryRequestPredicateFactory.java | 6 +- .../RemoteAddrRequestPredicateFactory.java | 6 +- .../support/ExchangeServerRequest.java | 232 ++++++++++++++++++ .../server/PublicDefaultServerRequest.java | 46 ---- .../BetweenRequestPredicateFactoryTests.java | 4 +- 7 files changed, 245 insertions(+), 60 deletions(-) create mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/support/ExchangeServerRequest.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java index 92ca0fcd6..907fbd31e 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java @@ -30,7 +30,7 @@ import org.springframework.cloud.gateway.model.Route; import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.tuple.Tuple; import org.springframework.tuple.TupleBuilder; -import org.springframework.web.reactive.function.server.PublicDefaultServerRequest; +import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest; import org.springframework.web.reactive.function.server.RequestPredicate; import org.springframework.web.reactive.handler.AbstractHandlerMapping; import org.springframework.web.server.ServerWebExchange; @@ -108,8 +108,7 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping { protected Mono lookupRoute(ServerWebExchange exchange) { return this.routeLocator.getRoutes() .map(this::getRouteCombinedPredicates) - //TODO: fix PublicDefaultServerRequest? - .filter(rcp -> rcp.combinedPredicate.test(new PublicDefaultServerRequest(exchange))) + .filter(rcp -> rcp.combinedPredicate.test(new ExchangeServerRequest(exchange))) .next() //TODO: error handling .map(rcp -> { diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java index 4af8d06a4..bd6d3e874 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java @@ -20,9 +20,9 @@ package org.springframework.cloud.gateway.handler.predicate; import java.util.Arrays; import java.util.List; +import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest; import org.springframework.http.HttpCookie; import org.springframework.tuple.Tuple; -import org.springframework.web.reactive.function.server.PublicDefaultServerRequest; import org.springframework.web.reactive.function.server.RequestPredicate; /** @@ -45,8 +45,8 @@ public class CookieRequestPredicateFactory implements RequestPredicateFactory { return request -> { //TODO: bad cast? - PublicDefaultServerRequest req = (PublicDefaultServerRequest) request; - List cookies = req.getCookies().get(name); + ExchangeServerRequest req = (ExchangeServerRequest) request; + List cookies = req.exchange().getRequest().getCookies().get(name); for (HttpCookie cookie : cookies) { if (cookie.getValue().matches(regexp)) { return true; diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java index 8381dab4c..20d642ad3 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java @@ -17,8 +17,8 @@ package org.springframework.cloud.gateway.handler.predicate; +import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest; import org.springframework.tuple.Tuple; -import org.springframework.web.reactive.function.server.PublicDefaultServerRequest; import org.springframework.web.reactive.function.server.RequestPredicate; import org.springframework.web.reactive.function.server.RequestPredicates; @@ -51,8 +51,8 @@ public class QueryRequestPredicateFactory implements RequestPredicateFactory { if (!args.hasFieldName(REGEXP_KEY)) { return req -> { //TODO: ServerRequest support for query params with no value - PublicDefaultServerRequest request = (PublicDefaultServerRequest) req; - return request.getExchange().getRequest().getQueryParams().containsKey(param); + ExchangeServerRequest request = (ExchangeServerRequest) req; + return request.exchange().getRequest().getQueryParams().containsKey(param); }; } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java index 28226a00b..c49f21f0b 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java @@ -26,7 +26,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.gateway.support.SubnetUtils; import org.springframework.tuple.Tuple; -import org.springframework.web.reactive.function.server.PublicDefaultServerRequest; +import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest; import org.springframework.web.reactive.function.server.RequestPredicate; /** @@ -48,8 +48,8 @@ public class RemoteAddrRequestPredicateFactory implements RequestPredicateFactor } return req -> { - PublicDefaultServerRequest serverRequest = (PublicDefaultServerRequest) req; - Optional remoteAddress = serverRequest.getExchange().getRequest().getRemoteAddress(); + ExchangeServerRequest serverRequest = (ExchangeServerRequest) req; + Optional remoteAddress = serverRequest.exchange().getRequest().getRemoteAddress(); if (remoteAddress.isPresent()) { String hostAddress = remoteAddress.get().getAddress().getHostAddress(); String host = req.uri().getHost(); diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/support/ExchangeServerRequest.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/support/ExchangeServerRequest.java new file mode 100644 index 000000000..5dae62351 --- /dev/null +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/support/ExchangeServerRequest.java @@ -0,0 +1,232 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.springframework.cloud.gateway.handler.support; + +import java.net.InetSocketAddress; +import java.net.URI; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRange; +import org.springframework.http.MediaType; +import org.springframework.http.codec.HttpMessageReader; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.Assert; +import org.springframework.web.reactive.function.BodyExtractor; +import org.springframework.web.reactive.function.BodyExtractors; +import org.springframework.web.reactive.function.UnsupportedMediaTypeException; +import org.springframework.web.reactive.function.server.HandlerStrategies; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.UnsupportedMediaTypeStatusException; +import org.springframework.web.server.WebSession; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * {@code ServerRequest} implementation based on a {@link ServerWebExchange}. + * + * @author Arjen Poutsma + * @since 1.0 + */ +public class ExchangeServerRequest implements ServerRequest { + + private static final Function ERROR_MAPPER = + ex -> ex.getContentType() + .map(contentType -> new UnsupportedMediaTypeStatusException(contentType, + ex.getSupportedMediaTypes())) + .orElseGet(() -> new UnsupportedMediaTypeStatusException(ex.getMessage())); + + private final ServerWebExchange exchange; + + private final Headers headers; + + private final HandlerStrategies strategies; + + public ExchangeServerRequest(ServerWebExchange exchange) { + this(exchange, HandlerStrategies.withDefaults()); + } + + public ExchangeServerRequest(ServerWebExchange exchange, HandlerStrategies strategies) { + this.exchange = exchange; + this.strategies = strategies; + this.headers = new ExchangeServerRequest.DefaultHeaders(); + } + + + @Override + public HttpMethod method() { + return request().getMethod(); + } + + @Override + public URI uri() { + return request().getURI(); + } + + @Override + public Headers headers() { + return this.headers; + } + + @Override + public T body(BodyExtractor extractor) { + return body(extractor, Collections.emptyMap()); + } + + @Override + public T body(BodyExtractor extractor, Map hints) { + Assert.notNull(extractor, "'extractor' must not be null"); + return extractor.extract(request(), + new BodyExtractor.Context() { + @Override + public Supplier>> messageReaders() { + return ExchangeServerRequest.this.strategies.messageReaders(); + } + @Override + public Map hints() { + return hints; + } + }); + } + + @Override + public Mono bodyToMono(Class elementClass) { + Mono mono = body(BodyExtractors.toMono(elementClass)); + return mono.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); + } + + @Override + public Flux bodyToFlux(Class elementClass) { + Flux flux = body(BodyExtractors.toFlux(elementClass)); + return flux.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); + } + + @Override + public Optional attribute(String name) { + return this.exchange.getAttribute(name); + } + + @Override + public Map attributes() { + return this.exchange.getAttributes(); + } + + @Override + public List queryParams(String name) { + List queryParams = request().getQueryParams().get(name); + return queryParams != null ? queryParams : Collections.emptyList(); + } + + @Override + public Map pathVariables() { + return this.exchange.>getAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE). + orElseGet(Collections::emptyMap); + } + + @Override + public Mono session() { + return this.exchange.getSession(); + } + + private ServerHttpRequest request() { + return this.exchange.getRequest(); + } + + public ServerWebExchange exchange() { + return this.exchange; + } + + @Override + public String toString() { + return String.format("%s %s", method(), path()); + } + + + private class DefaultHeaders implements Headers { + + private HttpHeaders delegate() { + return request().getHeaders(); + } + + @Override + public List accept() { + return delegate().getAccept(); + } + + @Override + public List acceptCharset() { + return delegate().getAcceptCharset(); + } + + @Override + public List acceptLanguage() { + return delegate().getAcceptLanguage(); + } + + @Override + public OptionalLong contentLength() { + long value = delegate().getContentLength(); + return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty()); + } + + @Override + public Optional contentType() { + return Optional.ofNullable(delegate().getContentType()); + } + + @Override + public InetSocketAddress host() { + return delegate().getHost(); + } + + @Override + public List range() { + return delegate().getRange(); + } + + @Override + public List header(String headerName) { + List headerValues = delegate().get(headerName); + return (headerValues != null ? headerValues : Collections.emptyList()); + } + + @Override + public HttpHeaders asHttpHeaders() { + return HttpHeaders.readOnlyHttpHeaders(delegate()); + } + + @Override + public String toString() { + return delegate().toString(); + } + } + +} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java b/spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java deleted file mode 100644 index 5e3396fa3..000000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.springframework.web.reactive.function.server; - -import org.springframework.http.HttpCookie; -import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ServerWebExchange; - -/** - * @author Spencer Gibb - */ -public class PublicDefaultServerRequest extends DefaultServerRequest { - private ServerWebExchange exchange; - - public PublicDefaultServerRequest(ServerWebExchange exchange) { - this(exchange, HandlerStrategies.withDefaults()); - } - - public PublicDefaultServerRequest(ServerWebExchange exchange, HandlerStrategies strategies) { - super(exchange, strategies); - this.exchange = exchange; - } - - public MultiValueMap getCookies() { - return this.exchange.getRequest().getCookies(); - } - - public ServerWebExchange getExchange() { - return exchange; - } -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java index b27ec8251..829f0a0e9 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java @@ -23,7 +23,7 @@ import java.time.format.DateTimeFormatter; import org.junit.Test; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.web.reactive.function.server.PublicDefaultServerRequest; +import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.server.adapter.DefaultServerWebExchange; @@ -122,6 +122,6 @@ public class BetweenRequestPredicateFactoryTests { static ServerRequest getRequest() { final MockServerHttpRequest request = MockServerHttpRequest.get("http://example.com").build(); - return new PublicDefaultServerRequest(new DefaultServerWebExchange(request, new MockServerHttpResponse())); + return new ExchangeServerRequest(new DefaultServerWebExchange(request, new MockServerHttpResponse())); } }