Skip to content

Commit 7194261

Browse files
committed
Merge branch '5.1.x'
2 parents 455ad71 + 23be5df commit 7194261

12 files changed

+139
-29
lines changed

spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteFlushProcessor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,17 @@ public <T> void onSubscribe(AbstractListenerWriteFlushProcessor<T> processor, Su
246246
super.onSubscribe(processor, subscription);
247247
}
248248
}
249+
250+
@Override
251+
public <T> void onComplete(AbstractListenerWriteFlushProcessor<T> processor) {
252+
// This can happen on (very early) completion notification from container..
253+
if (processor.changeState(this, COMPLETED)) {
254+
processor.resultPublisher.publishComplete();
255+
}
256+
else {
257+
processor.state.get().onComplete(processor);
258+
}
259+
}
249260
},
250261

251262
REQUESTED {

spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ public <T> void onSubscribe(AbstractListenerWriteProcessor<T> processor, Subscri
322322
super.onSubscribe(processor, subscription);
323323
}
324324
}
325+
326+
@Override
327+
public <T> void onComplete(AbstractListenerWriteProcessor<T> processor) {
328+
// This can happen on (very early) completion notification from container..
329+
processor.changeStateToComplete(this);
330+
}
325331
},
326332

327333
REQUESTED {

spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,13 @@ protected Mono<Void> doCommit(@Nullable Supplier<? extends Mono<Void>> writeActi
259259
protected abstract void applyStatusCode();
260260

261261
/**
262-
* Apply header changes from {@link #getHeaders()} to the underlying response.
263-
* This method is called once only.
262+
* Invoked when the response is getting committed allowing sub-classes to
263+
* make apply header values to the underlying response.
264+
* <p>Note that most sub-classes use an {@link HttpHeaders} instance that
265+
* wraps an adapter to the native response headers such that changes are
266+
* propagated to the underlying response on the go. That means this callback
267+
* is typically not used other than for specialized updates such as setting
268+
* the contentType or characterEncoding fields in a Servlet response.
264269
*/
265270
protected abstract void applyHeaders();
266271

spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,15 @@ private static HttpHeaders createHeaders(HttpServletResponse response) {
102102

103103
@Override
104104
protected void applyHeaders() {
105-
MediaType contentType = getHeaders().getContentType();
106105
HttpServletResponse response = getNativeResponse();
106+
MediaType contentType = null;
107+
try {
108+
contentType = getHeaders().getContentType();
109+
}
110+
catch (Exception ex) {
111+
String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
112+
response.setContentType(rawContentType);
113+
}
107114
if (response.getContentType() == null && contentType != null) {
108115
response.setContentType(contentType.toString());
109116
}

spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,25 @@ protected void applyHeaders() {
119119
this.response.addHeader(headerName, headerValue);
120120
}
121121
});
122-
MediaType contentType = getHeaders().getContentType();
122+
MediaType contentType = null;
123+
try {
124+
contentType = getHeaders().getContentType();
125+
}
126+
catch (Exception ex) {
127+
String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
128+
this.response.setContentType(rawContentType);
129+
}
123130
if (this.response.getContentType() == null && contentType != null) {
124131
this.response.setContentType(contentType.toString());
125132
}
126133
Charset charset = (contentType != null ? contentType.getCharset() : null);
127134
if (this.response.getCharacterEncoding() == null && charset != null) {
128135
this.response.setCharacterEncoding(charset.name());
129136
}
137+
long contentLength = getHeaders().getContentLength();
138+
if (contentLength != -1) {
139+
this.response.setContentLengthLong(contentLength);
140+
}
130141
}
131142

132143
@Override

spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,14 @@ else if (response instanceof HttpServletResponseWrapper) {
205205
@Override
206206
protected void applyHeaders() {
207207
HttpServletResponse response = getNativeResponse();
208-
MediaType contentType = getHeaders().getContentType();
208+
MediaType contentType = null;
209+
try {
210+
contentType = getHeaders().getContentType();
211+
}
212+
catch (Exception ex) {
213+
String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
214+
response.setContentType(rawContentType);
215+
}
209216
if (response.getContentType() == null && contentType != null) {
210217
response.setContentType(contentType.toString());
211218
}

spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ protected abstract void doFilterInternal(
248248
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
249249
FilterChain filterChain) throws ServletException, IOException {
250250

251-
doFilter(request, response, filterChain);
251+
filterChain.doFilter(request, response);
252252
}
253253

254254
}

spring-web/src/test/java/org/springframework/web/filter/OncePerRequestFilterTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
168168

169169
@Override
170170
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
171-
FilterChain filterChain) {
171+
FilterChain filterChain) throws ServletException, IOException {
172172

173173
this.didFilterNestedErrorDispatch = true;
174+
super.doFilterNestedErrorDispatch(request, response, filterChain);
174175
}
175176
}
176177

spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@
3333
import org.springframework.http.server.reactive.AbstractServerHttpRequest;
3434
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
3535
import org.springframework.http.server.reactive.ServerHttpRequest;
36+
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
3637
import org.springframework.http.server.reactive.ServerHttpResponse;
38+
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
3739
import org.springframework.lang.Nullable;
3840
import org.springframework.util.Assert;
3941
import org.springframework.web.reactive.socket.HandshakeInfo;
@@ -145,8 +147,8 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
145147
ServerHttpRequest request = exchange.getRequest();
146148
ServerHttpResponse response = exchange.getResponse();
147149

148-
HttpServletRequest servletRequest = getHttpServletRequest(request);
149-
HttpServletResponse servletResponse = getHttpServletResponse(response);
150+
HttpServletRequest servletRequest = getNativeRequest(request);
151+
HttpServletResponse servletResponse = getNativeResponse(response);
150152

151153
HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
152154
DataBufferFactory factory = response.bufferFactory();
@@ -174,14 +176,30 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
174176
return Mono.empty();
175177
}
176178

177-
private HttpServletRequest getHttpServletRequest(ServerHttpRequest request) {
178-
Assert.isInstanceOf(AbstractServerHttpRequest.class, request);
179-
return ((AbstractServerHttpRequest) request).getNativeRequest();
179+
private static HttpServletRequest getNativeRequest(ServerHttpRequest request) {
180+
if (request instanceof AbstractServerHttpRequest) {
181+
return ((AbstractServerHttpRequest) request).getNativeRequest();
182+
}
183+
else if (request instanceof ServerHttpRequestDecorator) {
184+
return getNativeRequest(((ServerHttpRequestDecorator) request).getDelegate());
185+
}
186+
else {
187+
throw new IllegalArgumentException(
188+
"Couldn't find HttpServletRequest in " + request.getClass().getName());
189+
}
180190
}
181191

182-
private HttpServletResponse getHttpServletResponse(ServerHttpResponse response) {
183-
Assert.isInstanceOf(AbstractServerHttpResponse.class, response);
184-
return ((AbstractServerHttpResponse) response).getNativeResponse();
192+
private static HttpServletResponse getNativeResponse(ServerHttpResponse response) {
193+
if (response instanceof AbstractServerHttpResponse) {
194+
return ((AbstractServerHttpResponse) response).getNativeResponse();
195+
}
196+
else if (response instanceof ServerHttpResponseDecorator) {
197+
return getNativeResponse(((ServerHttpResponseDecorator) response).getDelegate());
198+
}
199+
else {
200+
throw new IllegalArgumentException(
201+
"Couldn't find HttpServletResponse in " + response.getClass().getName());
202+
}
185203
}
186204

187205
private void startLazily(HttpServletRequest request) {

spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.core.io.buffer.NettyDataBufferFactory;
2626
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
2727
import org.springframework.http.server.reactive.ServerHttpResponse;
28+
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
2829
import org.springframework.lang.Nullable;
2930
import org.springframework.web.reactive.socket.HandshakeInfo;
3031
import org.springframework.web.reactive.socket.WebSocketHandler;
@@ -73,7 +74,7 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
7374
@Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) {
7475

7576
ServerHttpResponse response = exchange.getResponse();
76-
HttpServerResponse reactorResponse = ((AbstractServerHttpResponse) response).getNativeResponse();
77+
HttpServerResponse reactorResponse = getNativeResponse(response);
7778
HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
7879
NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory();
7980

@@ -87,4 +88,17 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
8788
});
8889
}
8990

91+
private static HttpServerResponse getNativeResponse(ServerHttpResponse response) {
92+
if (response instanceof AbstractServerHttpResponse) {
93+
return ((AbstractServerHttpResponse) response).getNativeResponse();
94+
}
95+
else if (response instanceof ServerHttpResponseDecorator) {
96+
return getNativeResponse(((ServerHttpResponseDecorator) response).getDelegate());
97+
}
98+
else {
99+
throw new IllegalArgumentException(
100+
"Couldn't find native response in " + response.getClass().getName());
101+
}
102+
}
103+
90104
}

spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@
3333
import org.springframework.http.server.reactive.AbstractServerHttpRequest;
3434
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
3535
import org.springframework.http.server.reactive.ServerHttpRequest;
36+
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
3637
import org.springframework.http.server.reactive.ServerHttpResponse;
38+
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
3739
import org.springframework.lang.Nullable;
3840
import org.springframework.util.Assert;
3941
import org.springframework.web.reactive.socket.HandshakeInfo;
@@ -131,8 +133,8 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
131133
ServerHttpRequest request = exchange.getRequest();
132134
ServerHttpResponse response = exchange.getResponse();
133135

134-
HttpServletRequest servletRequest = getHttpServletRequest(request);
135-
HttpServletResponse servletResponse = getHttpServletResponse(response);
136+
HttpServletRequest servletRequest = getNativeRequest(request);
137+
HttpServletResponse servletResponse = getNativeResponse(response);
136138

137139
HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
138140
DataBufferFactory bufferFactory = response.bufferFactory();
@@ -156,14 +158,30 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
156158
return Mono.empty();
157159
}
158160

159-
private HttpServletRequest getHttpServletRequest(ServerHttpRequest request) {
160-
Assert.isInstanceOf(AbstractServerHttpRequest.class, request, "ServletServerHttpRequest required");
161-
return ((AbstractServerHttpRequest) request).getNativeRequest();
161+
private static HttpServletRequest getNativeRequest(ServerHttpRequest request) {
162+
if (request instanceof AbstractServerHttpRequest) {
163+
return ((AbstractServerHttpRequest) request).getNativeRequest();
164+
}
165+
else if (request instanceof ServerHttpRequestDecorator) {
166+
return getNativeRequest(((ServerHttpRequestDecorator) request).getDelegate());
167+
}
168+
else {
169+
throw new IllegalArgumentException(
170+
"Couldn't find HttpServletRequest in " + request.getClass().getName());
171+
}
162172
}
163173

164-
private HttpServletResponse getHttpServletResponse(ServerHttpResponse response) {
165-
Assert.isInstanceOf(AbstractServerHttpResponse.class, response, "ServletServerHttpResponse required");
166-
return ((AbstractServerHttpResponse) response).getNativeResponse();
174+
private static HttpServletResponse getNativeResponse(ServerHttpResponse response) {
175+
if (response instanceof AbstractServerHttpResponse) {
176+
return ((AbstractServerHttpResponse) response).getNativeResponse();
177+
}
178+
else if (response instanceof ServerHttpResponseDecorator) {
179+
return getNativeResponse(((ServerHttpResponseDecorator) response).getDelegate());
180+
}
181+
else {
182+
throw new IllegalArgumentException(
183+
"Couldn't find HttpServletResponse in " + response.getClass().getName());
184+
}
167185
}
168186

169187
private WsServerContainer getContainer(HttpServletRequest request) {

spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/UndertowRequestUpgradeStrategy.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.core.io.buffer.DataBufferFactory;
3434
import org.springframework.http.server.reactive.AbstractServerHttpRequest;
3535
import org.springframework.http.server.reactive.ServerHttpRequest;
36+
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
3637
import org.springframework.lang.Nullable;
3738
import org.springframework.util.Assert;
3839
import org.springframework.web.reactive.socket.HandshakeInfo;
@@ -55,9 +56,7 @@ public class UndertowRequestUpgradeStrategy implements RequestUpgradeStrategy {
5556
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
5657
@Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) {
5758

58-
ServerHttpRequest request = exchange.getRequest();
59-
Assert.isInstanceOf(AbstractServerHttpRequest.class, request);
60-
HttpServerExchange httpExchange = ((AbstractServerHttpRequest) request).getNativeRequest();
59+
HttpServerExchange httpExchange = getNativeRequest(exchange.getRequest());
6160

6261
Set<String> protocols = (subProtocol != null ? Collections.singleton(subProtocol) : Collections.emptySet());
6362
Hybi13Handshake handshake = new Hybi13Handshake(protocols, false);
@@ -77,6 +76,19 @@ public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
7776
return Mono.empty();
7877
}
7978

79+
private static HttpServerExchange getNativeRequest(ServerHttpRequest request) {
80+
if (request instanceof AbstractServerHttpRequest) {
81+
return ((AbstractServerHttpRequest) request).getNativeRequest();
82+
}
83+
else if (request instanceof ServerHttpRequestDecorator) {
84+
return getNativeRequest(((ServerHttpRequestDecorator) request).getDelegate());
85+
}
86+
else {
87+
throw new IllegalArgumentException(
88+
"Couldn't find HttpServerExchange in " + request.getClass().getName());
89+
}
90+
}
91+
8092

8193
private class DefaultCallback implements WebSocketConnectionCallback {
8294

0 commit comments

Comments
 (0)