diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java index f7c9119c46e..830165989d4 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java @@ -19,6 +19,7 @@ package org.springframework.http.client; import java.io.Closeable; import java.io.IOException; import java.net.URI; +import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; @@ -68,9 +69,9 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest @Nullable private BiFunction httpContextFactory; - private int connectTimeout = -1; + private long connectTimeout = -1; - private int connectionRequestTimeout = -1; + private long connectionRequestTimeout = -1; /** * Create a new instance of the {@code HttpComponentsClientHttpRequestFactory} @@ -125,6 +126,26 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest this.connectTimeout = connectTimeout; } + /** + * Set the connection timeout for the underlying {@link RequestConfig}. + * A timeout value of 0 specifies an infinite timeout. + *

Additional properties can be configured by specifying a + * {@link RequestConfig} instance on a custom {@link HttpClient}. + *

This options does not affect connection timeouts for SSL + * handshakes or CONNECT requests; for that, it is required to + * use the {@link SocketConfig} on the + * {@link HttpClient} itself. + * @param connectTimeout the timeout value in milliseconds + * @since 6.1 + * @see RequestConfig#getConnectTimeout() + * @see SocketConfig#getSoTimeout + */ + public void setConnectTimeout(Duration connectTimeout) { + Assert.notNull(connectTimeout, "ConnectTimeout must not be null"); + Assert.isTrue(!connectTimeout.isNegative(), "Timeout must be a non-negative value"); + this.connectTimeout = connectTimeout.toMillis(); + } + /** * Set the timeout in milliseconds used when requesting a connection * from the connection manager using the underlying {@link RequestConfig}. @@ -139,6 +160,22 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest this.connectionRequestTimeout = connectionRequestTimeout; } + /** + * Set the timeout in milliseconds used when requesting a connection + * from the connection manager using the underlying {@link RequestConfig}. + * A timeout value of 0 specifies an infinite timeout. + *

Additional properties can be configured by specifying a + * {@link RequestConfig} instance on a custom {@link HttpClient}. + * @param connectionRequestTimeout the timeout value to request a connection in milliseconds + * @since 6.1 + * @see RequestConfig#getConnectionRequestTimeout() + */ + public void setConnectionRequestTimeout(Duration connectionRequestTimeout) { + Assert.notNull(connectionRequestTimeout, "ConnectionRequestTimeout must not be null"); + Assert.isTrue(!connectionRequestTimeout.isNegative(), "Timeout must be a non-negative value"); + this.connectionRequestTimeout = connectionRequestTimeout.toMillis(); + } + /** * Indicates whether this request factory should buffer the request body internally. *

Default is {@code true}. When sending large amounts of data via POST or PUT, it is diff --git a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequestFactory.java index 1ff226a8711..977e9da5f0f 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequestFactory.java @@ -89,6 +89,17 @@ public class JdkClientHttpRequestFactory implements ClientHttpRequestFactory { this.readTimeout = Duration.ofMillis(readTimeout); } + /** + * Set the underlying {@code HttpClient}'s read timeout as a + * {@code Duration}. + *

Default is the system's default timeout. + * @see java.net.http.HttpRequest.Builder#timeout + */ + public void setReadTimeout(Duration readTimeout) { + Assert.notNull(readTimeout, "ReadTimeout must not be null"); + this.readTimeout = readTimeout; + } + @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { diff --git a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java index 6d82669dffb..06fe2b69d22 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java @@ -46,10 +46,10 @@ class JettyClientHttpRequest extends AbstractStreamingClientHttpRequest { private final Request request; - private final int readTimeout; + private final long readTimeout; - public JettyClientHttpRequest(Request request, int readTimeout) { + public JettyClientHttpRequest(Request request, long readTimeout) { this.request = request; this.readTimeout = readTimeout; } diff --git a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequestFactory.java index 9daa2fddad9..56a7227aaae 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequestFactory.java @@ -18,6 +18,7 @@ package org.springframework.http.client; import java.io.IOException; import java.net.URI; +import java.time.Duration; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Request; @@ -40,7 +41,7 @@ public class JettyClientHttpRequestFactory implements ClientHttpRequestFactory, private final boolean defaultClient; - private int readTimeout = 1000; + private long readTimeout = 1000; /** @@ -66,21 +67,37 @@ public class JettyClientHttpRequestFactory implements ClientHttpRequestFactory, /** * Set the underlying connect timeout in milliseconds. - * A value of 0 specifies an infinite timeout. */ public void setConnectTimeout(int connectTimeout) { Assert.isTrue(connectTimeout >= 0, "Timeout must be a non-negative value"); this.httpClient.setConnectTimeout(connectTimeout); } + /** + * Set the underlying connect timeout in milliseconds. + * A value of 0 specifies an infinite timeout. + */ + public void setConnectTimeout(Duration connectTimeout) { + Assert.notNull(connectTimeout, "ConnectTimeout must not be null"); + this.httpClient.setConnectTimeout(connectTimeout.toMillis()); + } + /** * Set the underlying read timeout in milliseconds. */ - public void setReadTimeout(int readTimeout) { + public void setReadTimeout(long readTimeout) { Assert.isTrue(readTimeout > 0, "Timeout must be a positive value"); this.readTimeout = readTimeout; } + /** + * Set the underlying read timeout as {@code Duration}. + */ + public void setReadTimeout(Duration readTimeout) { + Assert.notNull(readTimeout, "ReadTimeout must not be null"); + this.readTimeout = readTimeout.toMillis(); + } + @Override public void afterPropertiesSet() throws Exception { startHttpClient(); diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java index 93232719d81..3287961da47 100644 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java @@ -18,6 +18,7 @@ package org.springframework.http.client; import java.io.IOException; import java.net.URI; +import java.time.Duration; import java.util.concurrent.TimeUnit; import okhttp3.Cache; @@ -72,6 +73,17 @@ public class OkHttp3ClientHttpRequestFactory implements ClientHttpRequestFactory .build(); } + /** + * Set the underlying read timeout in milliseconds. + * A value of 0 specifies an infinite timeout. + * @since 6.1 + */ + public void setReadTimeout(Duration readTimeout) { + this.client = this.client.newBuilder() + .readTimeout(readTimeout) + .build(); + } + /** * Set the underlying write timeout in milliseconds. * A value of 0 specifies an infinite timeout. @@ -82,6 +94,17 @@ public class OkHttp3ClientHttpRequestFactory implements ClientHttpRequestFactory .build(); } + /** + * Set the underlying write timeout in milliseconds. + * A value of 0 specifies an infinite timeout. + * @since 6.1 + */ + public void setWriteTimeout(Duration writeTimeout) { + this.client = this.client.newBuilder() + .writeTimeout(writeTimeout) + .build(); + } + /** * Set the underlying connect timeout in milliseconds. * A value of 0 specifies an infinite timeout. @@ -92,6 +115,17 @@ public class OkHttp3ClientHttpRequestFactory implements ClientHttpRequestFactory .build(); } + /** + * Set the underlying connect timeout in milliseconds. + * A value of 0 specifies an infinite timeout. + * @since 6.1 + */ + public void setConnectTimeout(Duration connectTimeout) { + this.client = this.client.newBuilder() + .connectTimeout(connectTimeout) + .build(); + } + @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index cc3ea82152d..925ffe04fd9 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -22,9 +22,11 @@ import java.net.Proxy; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.time.Duration; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * {@link ClientHttpRequestFactory} implementation that uses standard JDK facilities. @@ -98,6 +100,18 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory this.connectTimeout = connectTimeout; } + /** + * Set the underlying URLConnection's connect timeout as {@code Duration}. + * A timeout value of 0 specifies an infinite timeout. + *

Default is the system's default timeout. + * @since 6.1 + * @see URLConnection#setConnectTimeout(int) + */ + public void setConnectTimeout(Duration connectTimeout) { + Assert.notNull(connectTimeout, "ConnectTimeout must not be null"); + this.connectTimeout = (int) connectTimeout.toMillis(); + } + /** * Set the underlying URLConnection's read timeout (in milliseconds). * A timeout value of 0 specifies an infinite timeout. @@ -108,6 +122,18 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory this.readTimeout = readTimeout; } + /** + * Set the underlying URLConnection's read timeout (in milliseconds). + * A timeout value of 0 specifies an infinite timeout. + *

Default is the system's default timeout. + * @since 6.1 + * @see URLConnection#setReadTimeout(int) + */ + public void setReadTimeout(Duration readTimeout) { + Assert.notNull(readTimeout, "ReadTimeout must not be null"); + this.readTimeout = (int) readTimeout.toMillis(); + } + /** * Set if the underlying URLConnection can be set to 'output streaming' mode. * Default is {@code true}.