From 916ed5c0a9faa21a4ad3593f0a311c6b88ea6053 Mon Sep 17 00:00:00 2001 From: Matteo Cristoforo Date: Mon, 3 Jun 2024 14:05:28 +0200 Subject: [PATCH 1/2] Add support for specifying a read timeout for the reactive jdk client See gh-32941 --- .../client/reactive/JdkClientHttpConnector.java | 16 +++++++++++++++- .../client/reactive/JdkClientHttpRequest.java | 8 +++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java index 4313c658076..dccb5722862 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java @@ -21,6 +21,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.ByteBuffer; +import java.time.Duration; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -49,6 +50,9 @@ public class JdkClientHttpConnector implements ClientHttpConnector { private DataBufferFactory bufferFactory = DefaultDataBufferFactory.sharedInstance; + @Nullable + private Duration readTimeout = null; + /** * Default constructor that uses {@link HttpClient#newHttpClient()}. @@ -91,12 +95,22 @@ public class JdkClientHttpConnector implements ClientHttpConnector { this.bufferFactory = bufferFactory; } + /** + * Set the default read timeout to use. + *

By default, this is null, so no read timeout will be set.

+ */ + public void setReadTimeout(Duration readTimeout) { + Assert.notNull(readTimeout, "readTimeout is required"); + this.readTimeout = readTimeout; + } + @Override public Mono connect( HttpMethod method, URI uri, Function> requestCallback) { - JdkClientHttpRequest jdkClientHttpRequest = new JdkClientHttpRequest(method, uri, this.bufferFactory); + JdkClientHttpRequest jdkClientHttpRequest = new JdkClientHttpRequest(method, uri, this.bufferFactory, + this.readTimeout); return requestCallback.apply(jdkClientHttpRequest).then(Mono.defer(() -> { HttpRequest httpRequest = jdkClientHttpRequest.getNativeRequest(); diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpRequest.java index 2295d4ba2cb..9eeebb6b275 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpRequest.java @@ -20,6 +20,7 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.nio.ByteBuffer; +import java.time.Duration; import java.util.List; import java.util.Map; import java.util.concurrent.Flow; @@ -36,6 +37,7 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.HttpCookie; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; @@ -57,7 +59,8 @@ class JdkClientHttpRequest extends AbstractClientHttpRequest { private final HttpRequest.Builder builder; - public JdkClientHttpRequest(HttpMethod httpMethod, URI uri, DataBufferFactory bufferFactory) { + public JdkClientHttpRequest(HttpMethod httpMethod, URI uri, DataBufferFactory bufferFactory, + @Nullable Duration readTimeout) { Assert.notNull(httpMethod, "HttpMethod is required"); Assert.notNull(uri, "URI is required"); Assert.notNull(bufferFactory, "DataBufferFactory is required"); @@ -66,6 +69,9 @@ class JdkClientHttpRequest extends AbstractClientHttpRequest { this.uri = uri; this.bufferFactory = bufferFactory; this.builder = HttpRequest.newBuilder(uri); + if (readTimeout != null) { + this.builder.timeout(readTimeout); + } } From 329b53309a1f63b002620bad6c6a1dc743aaf731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 7 Jun 2024 17:05:22 +0200 Subject: [PATCH 2/2] Polish contribution See gh-32941 --- .../http/client/reactive/JdkClientHttpConnector.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java index dccb5722862..7424104a17c 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java @@ -96,8 +96,10 @@ public class JdkClientHttpConnector implements ClientHttpConnector { } /** - * Set the default read timeout to use. - *

By default, this is null, so no read timeout will be set.

+ * Set the underlying {@code HttpClient}'s read timeout as a {@code Duration}. + *

Default is the system's default timeout. + * @since 6.2 + * @see java.net.http.HttpRequest.Builder#timeout */ public void setReadTimeout(Duration readTimeout) { Assert.notNull(readTimeout, "readTimeout is required");