7 changed files with 245 additions and 60 deletions
@ -0,0 +1,232 @@
@@ -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<UnsupportedMediaTypeException, UnsupportedMediaTypeStatusException> 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> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor) { |
||||
return body(extractor, Collections.emptyMap()); |
||||
} |
||||
|
||||
@Override |
||||
public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor, Map<String, Object> hints) { |
||||
Assert.notNull(extractor, "'extractor' must not be null"); |
||||
return extractor.extract(request(), |
||||
new BodyExtractor.Context() { |
||||
@Override |
||||
public Supplier<Stream<HttpMessageReader<?>>> messageReaders() { |
||||
return ExchangeServerRequest.this.strategies.messageReaders(); |
||||
} |
||||
@Override |
||||
public Map<String, Object> hints() { |
||||
return hints; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) { |
||||
Mono<T> mono = body(BodyExtractors.toMono(elementClass)); |
||||
return mono.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); |
||||
} |
||||
|
||||
@Override |
||||
public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) { |
||||
Flux<T> flux = body(BodyExtractors.toFlux(elementClass)); |
||||
return flux.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); |
||||
} |
||||
|
||||
@Override |
||||
public <T> Optional<T> attribute(String name) { |
||||
return this.exchange.getAttribute(name); |
||||
} |
||||
|
||||
@Override |
||||
public Map<String, Object> attributes() { |
||||
return this.exchange.getAttributes(); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> queryParams(String name) { |
||||
List<String> queryParams = request().getQueryParams().get(name); |
||||
return queryParams != null ? queryParams : Collections.emptyList(); |
||||
} |
||||
|
||||
@Override |
||||
public Map<String, String> pathVariables() { |
||||
return this.exchange.<Map<String, String>>getAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE). |
||||
orElseGet(Collections::emptyMap); |
||||
} |
||||
|
||||
@Override |
||||
public Mono<WebSession> 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<MediaType> accept() { |
||||
return delegate().getAccept(); |
||||
} |
||||
|
||||
@Override |
||||
public List<Charset> acceptCharset() { |
||||
return delegate().getAcceptCharset(); |
||||
} |
||||
|
||||
@Override |
||||
public List<Locale.LanguageRange> acceptLanguage() { |
||||
return delegate().getAcceptLanguage(); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong contentLength() { |
||||
long value = delegate().getContentLength(); |
||||
return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty()); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<MediaType> contentType() { |
||||
return Optional.ofNullable(delegate().getContentType()); |
||||
} |
||||
|
||||
@Override |
||||
public InetSocketAddress host() { |
||||
return delegate().getHost(); |
||||
} |
||||
|
||||
@Override |
||||
public List<HttpRange> range() { |
||||
return delegate().getRange(); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> header(String headerName) { |
||||
List<String> 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(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,46 +0,0 @@
@@ -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<String, HttpCookie> getCookies() { |
||||
return this.exchange.getRequest().getCookies(); |
||||
} |
||||
|
||||
public ServerWebExchange getExchange() { |
||||
return exchange; |
||||
} |
||||
} |
Loading…
Reference in new issue