Skip to content

Commit 35b452b

Browse files
committed
Upgrade to Undertow 2.3.18.Final, dispatch in UndertowHttpHandlerAdapter
This ensures that the reactive handling of the request is dispatched from the Undertow IO thread, marking the exchange as async rather than ending it once the Undertow `handleRequest` method returns. Closes gh-33885
1 parent 56525da commit 35b452b

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

Diff for: framework-platform/framework-platform.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ dependencies {
5656
api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE")
5757
api("io.reactivex.rxjava3:rxjava:3.1.9")
5858
api("io.smallrye.reactive:mutiny:1.10.0")
59-
api("io.undertow:undertow-core:2.3.17.Final")
59+
api("io.undertow:undertow-core:2.3.18.Final")
6060
api("io.undertow:undertow-servlet:2.3.17.Final")
6161
api("io.undertow:undertow-websockets-jsr:2.3.17.Final")
6262
api("io.vavr:vavr:0.10.4")

Diff for: spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java

+18-16
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,27 @@ public DataBufferFactory getDataBufferFactory() {
6666

6767
@Override
6868
public void handleRequest(HttpServerExchange exchange) {
69-
UndertowServerHttpRequest request = null;
70-
try {
71-
request = new UndertowServerHttpRequest(exchange, getDataBufferFactory());
72-
}
73-
catch (URISyntaxException ex) {
74-
if (logger.isWarnEnabled()) {
75-
logger.debug("Failed to get request URI: " + ex.getMessage());
69+
exchange.dispatch(() -> {
70+
UndertowServerHttpRequest request = null;
71+
try {
72+
request = new UndertowServerHttpRequest(exchange, getDataBufferFactory());
7673
}
77-
exchange.setStatusCode(400);
78-
return;
79-
}
80-
ServerHttpResponse response = new UndertowServerHttpResponse(exchange, getDataBufferFactory(), request);
74+
catch (URISyntaxException ex) {
75+
if (logger.isWarnEnabled()) {
76+
logger.debug("Failed to get request URI: " + ex.getMessage());
77+
}
78+
exchange.setStatusCode(400);
79+
return;
80+
}
81+
ServerHttpResponse response = new UndertowServerHttpResponse(exchange, getDataBufferFactory(), request);
8182

82-
if (request.getMethod() == HttpMethod.HEAD) {
83-
response = new HttpHeadResponseDecorator(response);
84-
}
83+
if (request.getMethod() == HttpMethod.HEAD) {
84+
response = new HttpHeadResponseDecorator(response);
85+
}
8586

86-
HandlerResultSubscriber resultSubscriber = new HandlerResultSubscriber(exchange, request);
87-
this.httpHandler.handle(request, response).subscribe(resultSubscriber);
87+
HandlerResultSubscriber resultSubscriber = new HandlerResultSubscriber(exchange, request);
88+
this.httpHandler.handle(request, response).subscribe(resultSubscriber);
89+
});
8890
}
8991

9092

Diff for: spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingMessageConversionIntegrationTests.java

+17
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.web.reactive.result.method.annotation;
1818

1919
import java.nio.ByteBuffer;
20+
import java.time.Duration;
2021
import java.util.ArrayList;
2122
import java.util.Arrays;
2223
import java.util.Collections;
@@ -331,6 +332,17 @@ void personTransformWithFlux(HttpServer httpServer) throws Exception {
331332
assertThat(performPost("/person-transform/flux", JSON, req, JSON, PERSON_LIST).getBody()).isEqualTo(res);
332333
}
333334

335+
@ParameterizedHttpServerTest // see gh-33885
336+
void personTransformWithFluxDelayed(HttpServer httpServer) throws Exception {
337+
startServer(httpServer);
338+
339+
List<?> req = asList(new Person("Robert"), new Person("Marie"));
340+
List<?> res = asList(new Person("ROBERT"), new Person("MARIE"));
341+
assertThat(performPost("/person-transform/flux-delayed", JSON, req, JSON, PERSON_LIST))
342+
.satisfies(r -> assertThat(r.getBody()).isEqualTo(res))
343+
.satisfies(r -> assertThat(r.getHeaders().getContentLength()).isNotZero());
344+
}
345+
334346
@ParameterizedHttpServerTest
335347
void personTransformWithObservable(HttpServer httpServer) throws Exception {
336348
startServer(httpServer);
@@ -632,6 +644,11 @@ Flux<Person> transformFlux(@RequestBody Flux<Person> persons) {
632644
return persons.map(person -> new Person(person.getName().toUpperCase()));
633645
}
634646

647+
@PostMapping("/flux-delayed")
648+
Flux<Person> transformDelayed(@RequestBody Flux<Person> persons) {
649+
return transformFlux(persons).delayElements(Duration.ofMillis(10));
650+
}
651+
635652
@PostMapping("/observable")
636653
Observable<Person> transformObservable(@RequestBody Observable<Person> persons) {
637654
return persons.map(person -> new Person(person.getName().toUpperCase()));

0 commit comments

Comments
 (0)