Add base classes for ServerHttpRequest/Response impls
This commit is contained in:
parent
eedc90818f
commit
f8ef2e0220
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.http.server.reactive;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Common base class for {@link ServerHttpRequest} implementations.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
|
||||
|
||||
private URI uri;
|
||||
|
||||
private HttpHeaders headers;
|
||||
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
if (this.uri == null) {
|
||||
try {
|
||||
this.uri = initUri();
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a URI that represents the request.
|
||||
* Invoked lazily on the first call to {@link #getURI()} and then cached.
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
protected abstract URI initUri() throws URISyntaxException;
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.headers == null) {
|
||||
this.headers = HttpHeaders.readOnlyHttpHeaders(initHeaders());
|
||||
}
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the headers from the underlying request.
|
||||
* Invoked lazily on the first call to {@link #getHeaders()} and then cached.
|
||||
*/
|
||||
protected abstract HttpHeaders initHeaders();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.http.server.reactive;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.Flux;
|
||||
import reactor.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Base class for {@link ServerHttpResponse} implementations.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
protected AbstractServerHttpResponse() {
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return (this.headersWritten ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setBody(Publisher<ByteBuffer> publisher) {
|
||||
return Flux.from(publisher).lift(new WriteWithOperator<>(writeWithPublisher -> {
|
||||
writeHeaders();
|
||||
return setBodyInternal(writeWithPublisher);
|
||||
})).after();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to write to the underlying the response.
|
||||
* @param publisher the publisher to write with
|
||||
*/
|
||||
protected abstract Mono<Void> setBodyInternal(Publisher<ByteBuffer> publisher);
|
||||
|
||||
@Override
|
||||
public void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
try {
|
||||
writeHeadersInternal();
|
||||
}
|
||||
finally {
|
||||
this.headersWritten = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to apply header changes from {@link #getHeaders()}
|
||||
* to the underlying response. This method is protected from being called
|
||||
* more than once.
|
||||
*/
|
||||
protected abstract void writeHeadersInternal();
|
||||
|
||||
}
|
||||
|
|
@ -32,14 +32,10 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Stephane Maldini
|
||||
*/
|
||||
public class ReactorServerHttpRequest implements ServerHttpRequest {
|
||||
public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
|
||||
|
||||
private final HttpChannel<Buffer, ?> channel;
|
||||
|
||||
private URI uri;
|
||||
|
||||
private HttpHeaders headers;
|
||||
|
||||
|
||||
public ReactorServerHttpRequest(HttpChannel<Buffer, ?> request) {
|
||||
Assert.notNull("'request' must not be null.");
|
||||
|
|
@ -57,27 +53,17 @@ public class ReactorServerHttpRequest implements ServerHttpRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
if (this.uri == null) {
|
||||
try {
|
||||
this.uri = new URI(this.channel.uri());
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return this.uri;
|
||||
protected URI initUri() throws URISyntaxException {
|
||||
return new URI(this.channel.uri());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
for (String name : this.channel.headers().names()) {
|
||||
this.headers.put(name, this.channel.headers().getAll(name));
|
||||
}
|
||||
protected HttpHeaders initHeaders() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
for (String name : this.channel.headers().names()) {
|
||||
headers.put(name, this.channel.headers().getAll(name));
|
||||
}
|
||||
return this.headers;
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import reactor.io.buffer.Buffer;
|
|||
import reactor.io.net.http.HttpChannel;
|
||||
import reactor.io.net.http.model.Status;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
|
@ -34,19 +33,14 @@ import org.springframework.util.Assert;
|
|||
* @author Stephane Maldini
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ReactorServerHttpResponse implements ServerHttpResponse {
|
||||
public class ReactorServerHttpResponse extends AbstractServerHttpResponse {
|
||||
|
||||
private final HttpChannel<?, Buffer> channel;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
public ReactorServerHttpResponse(HttpChannel<?, Buffer> response) {
|
||||
Assert.notNull("'response' must not be null.");
|
||||
this.channel = response;
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -60,29 +54,16 @@ public class ReactorServerHttpResponse implements ServerHttpResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return (this.headersWritten ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setBody(Publisher<ByteBuffer> publisher) {
|
||||
return Flux.from(publisher).lift(new WriteWithOperator<>(this::setBodyInternal)).after();
|
||||
}
|
||||
|
||||
protected Mono<Void> setBodyInternal(Publisher<ByteBuffer> publisher) {
|
||||
writeHeaders();
|
||||
return Mono.from(getReactorChannel().writeWith(Flux.from(publisher).map(Buffer::new)));
|
||||
return Mono.from(this.channel.writeWith(Flux.from(publisher).map(Buffer::new)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
for (String name : this.headers.keySet()) {
|
||||
for (String value : this.headers.get(name)) {
|
||||
this.channel.responseHeaders().add(name, value);
|
||||
}
|
||||
protected void writeHeadersInternal() {
|
||||
for (String name : getHeaders().keySet()) {
|
||||
for (String value : getHeaders().get(name)) {
|
||||
this.channel.responseHeaders().add(name, value);
|
||||
}
|
||||
this.headersWritten = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,14 +36,10 @@ import org.springframework.util.Assert;
|
|||
* @author Rossen Stoyanchev
|
||||
* @author Stephane Maldini
|
||||
*/
|
||||
public class RxNettyServerHttpRequest implements ServerHttpRequest {
|
||||
public class RxNettyServerHttpRequest extends AbstractServerHttpRequest {
|
||||
|
||||
private final HttpServerRequest<ByteBuf> request;
|
||||
|
||||
private URI uri;
|
||||
|
||||
private HttpHeaders headers;
|
||||
|
||||
|
||||
public RxNettyServerHttpRequest(HttpServerRequest<ByteBuf> request) {
|
||||
Assert.notNull("'request', request must not be null.");
|
||||
|
|
@ -61,27 +57,17 @@ public class RxNettyServerHttpRequest implements ServerHttpRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
if (this.uri == null) {
|
||||
try {
|
||||
this.uri = new URI(this.getRxNettyRequest().getUri());
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return this.uri;
|
||||
protected URI initUri() throws URISyntaxException {
|
||||
return new URI(this.getRxNettyRequest().getUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
for (String name : this.getRxNettyRequest().getHeaderNames()) {
|
||||
this.headers.put(name, this.getRxNettyRequest().getAllHeaderValues(name));
|
||||
}
|
||||
protected HttpHeaders initHeaders() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
for (String name : this.getRxNettyRequest().getHeaderNames()) {
|
||||
headers.put(name, this.getRxNettyRequest().getAllHeaderValues(name));
|
||||
}
|
||||
return this.headers;
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -36,19 +36,14 @@ import org.springframework.util.Assert;
|
|||
* @author Rossen Stoyanchev
|
||||
* @author Stephane Maldini
|
||||
*/
|
||||
public class RxNettyServerHttpResponse implements ServerHttpResponse {
|
||||
public class RxNettyServerHttpResponse extends AbstractServerHttpResponse {
|
||||
|
||||
private final HttpServerResponse<?> response;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
public RxNettyServerHttpResponse(HttpServerResponse<?> response) {
|
||||
Assert.notNull("'response', response must not be null.");
|
||||
this.response = response;
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -62,17 +57,7 @@ public class RxNettyServerHttpResponse implements ServerHttpResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return (this.headersWritten ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setBody(Publisher<ByteBuffer> publisher) {
|
||||
return Flux.from(publisher).lift(new WriteWithOperator<>(this::setBodyInternal)).after();
|
||||
}
|
||||
|
||||
protected Mono<Void> setBodyInternal(Publisher<ByteBuffer> publisher) {
|
||||
writeHeaders();
|
||||
Observable<byte[]> content = RxJava1Converter.from(publisher).map(this::toBytes);
|
||||
Observable<Void> completion = getRxNettyResponse().writeBytes(content);
|
||||
return RxJava1Converter.from(completion).after();
|
||||
|
|
@ -85,13 +70,10 @@ public class RxNettyServerHttpResponse implements ServerHttpResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
for (String name : this.headers.keySet()) {
|
||||
for (String value : this.headers.get(name))
|
||||
protected void writeHeadersInternal() {
|
||||
for (String name : getHeaders().keySet()) {
|
||||
for (String value : getHeaders().get(name))
|
||||
this.response.addHeader(name, value);
|
||||
}
|
||||
this.headersWritten = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,14 +39,10 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ServletServerHttpRequest implements ServerHttpRequest {
|
||||
public class ServletServerHttpRequest extends AbstractServerHttpRequest {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private URI uri;
|
||||
|
||||
private HttpHeaders headers;
|
||||
|
||||
private final Flux<ByteBuffer> requestBodyPublisher;
|
||||
|
||||
|
||||
|
|
@ -68,62 +64,48 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
if (this.uri == null) {
|
||||
try {
|
||||
this.uri = new URI(getServletRequest().getScheme(), null,
|
||||
getServletRequest().getServerName(),
|
||||
getServletRequest().getServerPort(),
|
||||
getServletRequest().getRequestURI(),
|
||||
getServletRequest().getQueryString(), null);
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException("Could not get HttpServletRequest URI: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return this.uri;
|
||||
protected URI initUri() throws URISyntaxException {
|
||||
return new URI(getServletRequest().getScheme(), null,
|
||||
getServletRequest().getServerName(),
|
||||
getServletRequest().getServerPort(),
|
||||
getServletRequest().getRequestURI(),
|
||||
getServletRequest().getQueryString(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
for (Enumeration<?> names = getServletRequest().getHeaderNames(); names.hasMoreElements(); ) {
|
||||
String headerName = (String) names.nextElement();
|
||||
for (Enumeration<?> headerValues = getServletRequest().getHeaders(headerName);
|
||||
headerValues.hasMoreElements(); ) {
|
||||
String headerValue = (String) headerValues.nextElement();
|
||||
this.headers.add(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
// HttpServletRequest exposes some headers as properties: we should include those if not already present
|
||||
MediaType contentType = this.headers.getContentType();
|
||||
if (contentType == null) {
|
||||
String requestContentType = getServletRequest().getContentType();
|
||||
if (StringUtils.hasLength(requestContentType)) {
|
||||
contentType = MediaType.parseMediaType(requestContentType);
|
||||
this.headers.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
if (contentType != null && contentType.getCharSet() == null) {
|
||||
String requestEncoding = getServletRequest().getCharacterEncoding();
|
||||
if (StringUtils.hasLength(requestEncoding)) {
|
||||
Charset charSet = Charset.forName(requestEncoding);
|
||||
Map<String, String> params = new LinkedCaseInsensitiveMap<>();
|
||||
params.putAll(contentType.getParameters());
|
||||
params.put("charset", charSet.toString());
|
||||
MediaType newContentType = new MediaType(contentType.getType(), contentType.getSubtype(), params);
|
||||
this.headers.setContentType(newContentType);
|
||||
}
|
||||
}
|
||||
if (this.headers.getContentLength() == -1) {
|
||||
int requestContentLength = getServletRequest().getContentLength();
|
||||
if (requestContentLength != -1) {
|
||||
this.headers.setContentLength(requestContentLength);
|
||||
}
|
||||
protected HttpHeaders initHeaders() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
for (Enumeration<?> names = getServletRequest().getHeaderNames(); names.hasMoreElements(); ) {
|
||||
String name = (String) names.nextElement();
|
||||
for (Enumeration<?> values = getServletRequest().getHeaders(name); values.hasMoreElements(); ) {
|
||||
headers.add(name, (String) values.nextElement());
|
||||
}
|
||||
}
|
||||
return this.headers;
|
||||
MediaType contentType = headers.getContentType();
|
||||
if (contentType == null) {
|
||||
String requestContentType = getServletRequest().getContentType();
|
||||
if (StringUtils.hasLength(requestContentType)) {
|
||||
contentType = MediaType.parseMediaType(requestContentType);
|
||||
headers.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
if (contentType != null && contentType.getCharSet() == null) {
|
||||
String encoding = getServletRequest().getCharacterEncoding();
|
||||
if (StringUtils.hasLength(encoding)) {
|
||||
Charset charset = Charset.forName(encoding);
|
||||
Map<String, String> params = new LinkedCaseInsensitiveMap<>();
|
||||
params.putAll(contentType.getParameters());
|
||||
params.put("charset", charset.toString());
|
||||
headers.setContentType(new MediaType(contentType.getType(), contentType.getSubtype(), params));
|
||||
}
|
||||
}
|
||||
if (headers.getContentLength() == -1) {
|
||||
int contentLength = getServletRequest().getContentLength();
|
||||
if (contentLength != -1) {
|
||||
headers.setContentLength(contentLength);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ import java.util.function.Function;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.Flux;
|
||||
import reactor.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -37,16 +35,12 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ServletServerHttpResponse implements ServerHttpResponse {
|
||||
public class ServletServerHttpResponse extends AbstractServerHttpResponse {
|
||||
|
||||
private final HttpServletResponse response;
|
||||
|
||||
private final Function<Publisher<ByteBuffer>, Mono<Void>> responseBodyWriter;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
public ServletServerHttpResponse(HttpServletResponse response,
|
||||
Function<Publisher<ByteBuffer>, Mono<Void>> responseBodyWriter) {
|
||||
|
|
@ -55,7 +49,6 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
|||
Assert.notNull(responseBodyWriter, "'responseBodyWriter' must not be null");
|
||||
this.response = response;
|
||||
this.responseBodyWriter = responseBodyWriter;
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -69,38 +62,25 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return (this.headersWritten ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setBody(final Publisher<ByteBuffer> publisher) {
|
||||
return Flux.from(publisher).lift(new WriteWithOperator<>(this::setBodyInternal)).after();
|
||||
}
|
||||
|
||||
protected Mono<Void> setBodyInternal(Publisher<ByteBuffer> publisher) {
|
||||
writeHeaders();
|
||||
return this.responseBodyWriter.apply(publisher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
for (Map.Entry<String, List<String>> entry : this.headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.response.addHeader(headerName, headerValue);
|
||||
}
|
||||
protected void writeHeadersInternal() {
|
||||
for (Map.Entry<String, List<String>> entry : getHeaders().entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.response.addHeader(headerName, headerValue);
|
||||
}
|
||||
MediaType contentType = this.headers.getContentType();
|
||||
if (this.response.getContentType() == null && contentType != null) {
|
||||
this.response.setContentType(contentType.toString());
|
||||
}
|
||||
Charset charset = (contentType != null ? contentType.getCharSet() : null);
|
||||
if (this.response.getCharacterEncoding() == null && charset != null) {
|
||||
this.response.setCharacterEncoding(charset.name());
|
||||
}
|
||||
this.headersWritten = true;
|
||||
}
|
||||
MediaType contentType = getHeaders().getContentType();
|
||||
if (this.response.getContentType() == null && contentType != null) {
|
||||
this.response.setContentType(contentType.toString());
|
||||
}
|
||||
Charset charset = (contentType != null ? contentType.getCharSet() : null);
|
||||
if (this.response.getCharacterEncoding() == null && charset != null) {
|
||||
this.response.setCharacterEncoding(charset.name());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,14 +35,10 @@ import org.springframework.util.Assert;
|
|||
* @author Marek Hawrylczak
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class UndertowServerHttpRequest implements ServerHttpRequest {
|
||||
public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
|
||||
|
||||
private final HttpServerExchange exchange;
|
||||
|
||||
private URI uri;
|
||||
|
||||
private HttpHeaders headers;
|
||||
|
||||
private final Flux<ByteBuffer> body;
|
||||
|
||||
|
||||
|
|
@ -64,31 +60,19 @@ public class UndertowServerHttpRequest implements ServerHttpRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
if (this.uri == null) {
|
||||
try {
|
||||
return new URI(this.getUndertowExchange().getRequestScheme(), null,
|
||||
this.getUndertowExchange().getHostName(),
|
||||
this.getUndertowExchange().getHostPort(),
|
||||
this.getUndertowExchange().getRequestURI(),
|
||||
this.getUndertowExchange().getQueryString(), null);
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return this.uri;
|
||||
protected URI initUri() throws URISyntaxException {
|
||||
return new URI(this.exchange.getRequestScheme(), null,
|
||||
this.exchange.getHostName(), this.exchange.getHostPort(),
|
||||
this.exchange.getRequestURI(), this.exchange.getQueryString(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
for (HeaderValues values : this.getUndertowExchange().getRequestHeaders()) {
|
||||
this.headers.put(values.getHeaderName().toString(), values);
|
||||
}
|
||||
protected HttpHeaders initHeaders() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
for (HeaderValues values : this.getUndertowExchange().getRequestHeaders()) {
|
||||
headers.put(values.getHeaderName().toString(), values);
|
||||
}
|
||||
return this.headers;
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ import java.util.function.Function;
|
|||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.util.HttpString;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.Flux;
|
||||
import reactor.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
|
@ -37,16 +35,12 @@ import org.springframework.util.Assert;
|
|||
* @author Marek Hawrylczak
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class UndertowServerHttpResponse implements ServerHttpResponse {
|
||||
public class UndertowServerHttpResponse extends AbstractServerHttpResponse {
|
||||
|
||||
private final HttpServerExchange exchange;
|
||||
|
||||
private final Function<Publisher<ByteBuffer>, Mono<Void>> responseBodyWriter;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
public UndertowServerHttpResponse(HttpServerExchange exchange,
|
||||
Function<Publisher<ByteBuffer>, Mono<Void>> responseBodyWriter) {
|
||||
|
|
@ -55,7 +49,6 @@ public class UndertowServerHttpResponse implements ServerHttpResponse {
|
|||
Assert.notNull(responseBodyWriter, "'responseBodyWriter' must not be null");
|
||||
this.exchange = exchange;
|
||||
this.responseBodyWriter = responseBodyWriter;
|
||||
this.headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -70,28 +63,15 @@ public class UndertowServerHttpResponse implements ServerHttpResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return (this.headersWritten ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setBody(Publisher<ByteBuffer> publisher) {
|
||||
return Flux.from(publisher).lift(new WriteWithOperator<>(this::setBodyInternal)).after();
|
||||
}
|
||||
|
||||
protected Mono<Void> setBodyInternal(Publisher<ByteBuffer> publisher) {
|
||||
writeHeaders();
|
||||
return this.responseBodyWriter.apply(publisher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
for (Map.Entry<String, List<String>> entry : this.headers.entrySet()) {
|
||||
HttpString headerName = HttpString.tryFromString(entry.getKey());
|
||||
this.exchange.getResponseHeaders().addAll(headerName, entry.getValue());
|
||||
}
|
||||
this.headersWritten = true;
|
||||
protected void writeHeadersInternal() {
|
||||
for (Map.Entry<String, List<String>> entry : getHeaders().entrySet()) {
|
||||
HttpString headerName = HttpString.tryFromString(entry.getKey());
|
||||
this.exchange.getResponseHeaders().addAll(headerName, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue