001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.reactive.function.server.support;
018
019import java.net.InetSocketAddress;
020import java.net.URI;
021import java.nio.charset.Charset;
022import java.security.Principal;
023import java.util.List;
024import java.util.Locale;
025import java.util.Map;
026import java.util.Optional;
027import java.util.OptionalLong;
028
029import reactor.core.publisher.Flux;
030import reactor.core.publisher.Mono;
031
032import org.springframework.core.ParameterizedTypeReference;
033import org.springframework.http.HttpCookie;
034import org.springframework.http.HttpHeaders;
035import org.springframework.http.HttpMethod;
036import org.springframework.http.HttpRange;
037import org.springframework.http.MediaType;
038import org.springframework.http.codec.HttpMessageReader;
039import org.springframework.http.codec.multipart.Part;
040import org.springframework.http.server.PathContainer;
041import org.springframework.http.server.reactive.ServerHttpRequest;
042import org.springframework.util.Assert;
043import org.springframework.util.MultiValueMap;
044import org.springframework.web.reactive.function.BodyExtractor;
045import org.springframework.web.reactive.function.server.ServerRequest;
046import org.springframework.web.server.ServerWebExchange;
047import org.springframework.web.server.WebSession;
048import org.springframework.web.util.UriBuilder;
049
050/**
051 * Implementation of the {@link ServerRequest} interface that can be subclassed
052 * to adapt the request in a
053 * {@link org.springframework.web.reactive.function.server.HandlerFilterFunction handler filter function}.
054 * All methods default to calling through to the wrapped request.
055 *
056 * @author Arjen Poutsma
057 * @since 5.0
058 */
059public class ServerRequestWrapper implements ServerRequest {
060
061        private final ServerRequest delegate;
062
063
064        /**
065         * Create a new {@code ServerRequestWrapper} that wraps the given request.
066         * @param delegate the request to wrap
067         */
068        public ServerRequestWrapper(ServerRequest delegate) {
069                Assert.notNull(delegate, "Delegate must not be null");
070                this.delegate = delegate;
071        }
072
073
074        /**
075         * Return the wrapped request.
076         */
077        public ServerRequest request() {
078                return this.delegate;
079        }
080
081        @Override
082        public HttpMethod method() {
083                return this.delegate.method();
084        }
085
086        @Override
087        public String methodName() {
088                return this.delegate.methodName();
089        }
090
091        @Override
092        public URI uri() {
093                return this.delegate.uri();
094        }
095
096        @Override
097        public UriBuilder uriBuilder() {
098                return this.delegate.uriBuilder();
099        }
100
101        @Override
102        public String path() {
103                return this.delegate.path();
104        }
105
106        @Override
107        public PathContainer pathContainer() {
108                return this.delegate.pathContainer();
109        }
110
111        @Override
112        public Headers headers() {
113                return this.delegate.headers();
114        }
115
116        @Override
117        public MultiValueMap<String, HttpCookie> cookies() {
118                return this.delegate.cookies();
119        }
120
121        @Override
122        public Optional<InetSocketAddress> remoteAddress() {
123                return this.delegate.remoteAddress();
124        }
125
126        @Override
127        public Optional<InetSocketAddress> localAddress() {
128                return this.delegate.localAddress();
129        }
130
131        @Override
132        public List<HttpMessageReader<?>> messageReaders() {
133                return this.delegate.messageReaders();
134        }
135
136        @Override
137        public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor) {
138                return this.delegate.body(extractor);
139        }
140
141        @Override
142        public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor, Map<String, Object> hints) {
143                return this.delegate.body(extractor, hints);
144        }
145
146        @Override
147        public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) {
148                return this.delegate.bodyToMono(elementClass);
149        }
150
151        @Override
152        public <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> typeReference) {
153                return this.delegate.bodyToMono(typeReference);
154        }
155
156        @Override
157        public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) {
158                return this.delegate.bodyToFlux(elementClass);
159        }
160
161        @Override
162        public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference) {
163                return this.delegate.bodyToFlux(typeReference);
164        }
165
166        @Override
167        public Optional<Object> attribute(String name) {
168                return this.delegate.attribute(name);
169        }
170
171        @Override
172        public Map<String, Object> attributes() {
173                return this.delegate.attributes();
174        }
175
176        @Override
177        public Optional<String> queryParam(String name) {
178                return this.delegate.queryParam(name);
179        }
180
181        @Override
182        public MultiValueMap<String, String> queryParams() {
183                return this.delegate.queryParams();
184        }
185
186        @Override
187        public String pathVariable(String name) {
188                return this.delegate.pathVariable(name);
189        }
190
191        @Override
192        public Map<String, String> pathVariables() {
193                return this.delegate.pathVariables();
194        }
195
196        @Override
197        public Mono<WebSession> session() {
198                return this.delegate.session();
199        }
200
201        @Override
202        public Mono<? extends Principal> principal() {
203                return this.delegate.principal();
204        }
205
206        @Override
207        public Mono<MultiValueMap<String, String>> formData() {
208                return this.delegate.formData();
209        }
210
211        @Override
212        public Mono<MultiValueMap<String, Part>> multipartData() {
213                return this.delegate.multipartData();
214        }
215
216        @Override
217        public ServerWebExchange exchange() {
218                return this.delegate.exchange();
219        }
220
221        /**
222         * Implementation of the {@code Headers} interface that can be subclassed
223         * to adapt the headers in a
224         * {@link org.springframework.web.reactive.function.server.HandlerFilterFunction handler filter function}.
225         * All methods default to calling through to the wrapped headers.
226         */
227        public static class HeadersWrapper implements ServerRequest.Headers {
228
229                private final Headers headers;
230
231                /**
232                 * Create a new {@code HeadersWrapper} that wraps the given request.
233                 * @param headers the headers to wrap
234                 */
235                public HeadersWrapper(Headers headers) {
236                        Assert.notNull(headers, "Headers must not be null");
237                        this.headers = headers;
238                }
239
240                @Override
241                public List<MediaType> accept() {
242                        return this.headers.accept();
243                }
244
245                @Override
246                public List<Charset> acceptCharset() {
247                        return this.headers.acceptCharset();
248                }
249
250                @Override
251                public List<Locale.LanguageRange> acceptLanguage() {
252                        return this.headers.acceptLanguage();
253                }
254
255                @Override
256                public OptionalLong contentLength() {
257                        return this.headers.contentLength();
258                }
259
260                @Override
261                public Optional<MediaType> contentType() {
262                        return this.headers.contentType();
263                }
264
265                @Override
266                public InetSocketAddress host() {
267                        return this.headers.host();
268                }
269
270                @Override
271                public List<HttpRange> range() {
272                        return this.headers.range();
273                }
274
275                @Override
276                public List<String> header(String headerName) {
277                        return this.headers.header(headerName);
278                }
279
280                @Override
281                public HttpHeaders asHttpHeaders() {
282                        return this.headers.asHttpHeaders();
283                }
284        }
285
286}