From e24ebd6dbb1b2e3d5ce25c275c3ce900ddf8869b Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 27 Feb 2015 15:36:59 +0100 Subject: [PATCH] Add connect/read timeout to Netty RequestFactory Added connectTimeout and readTimeout properties to the Netty4ClientHttpRequestFactory. Issue: SPR-12612 --- .../Netty4ClientHttpRequestFactory.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java index 32f233af63..8971f232d1 100644 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java @@ -18,17 +18,22 @@ package org.springframework.http.client; import java.io.IOException; import java.net.URI; +import java.net.URLConnection; +import java.util.concurrent.TimeUnit; import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelConfig; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.SocketChannelConfig; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.HttpClientCodec; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.ssl.SslContext; +import io.netty.handler.timeout.ReadTimeoutHandler; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -67,6 +72,10 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, private volatile Bootstrap bootstrap; + private int connectTimeout = -1; + + private int readTimeout = -1; + /** * Create a new {@code Netty4ClientHttpRequestFactory} with a default @@ -111,6 +120,24 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, this.sslContext = sslContext; } + /** + * Set the underlying connect timeout (in milliseconds). + * A timeout value of 0 specifies an infinite timeout. + * @see ChannelConfig#setConnectTimeoutMillis(int) + */ + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + /** + * Set the underlying URLConnection's read timeout (in milliseconds). + * A timeout value of 0 specifies an infinite timeout. + * @see ReadTimeoutHandler + */ + public void setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + } + private Bootstrap getBootstrap() { if (this.bootstrap == null) { Bootstrap bootstrap = new Bootstrap(); @@ -118,12 +145,17 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, .handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel channel) throws Exception { + configureChannel(channel.config()); ChannelPipeline pipeline = channel.pipeline(); if (sslContext != null) { pipeline.addLast(sslContext.newHandler(channel.alloc())); } pipeline.addLast(new HttpClientCodec()); pipeline.addLast(new HttpObjectAggregator(maxResponseSize)); + if (readTimeout > 0) { + pipeline.addLast(new ReadTimeoutHandler(readTimeout, + TimeUnit.MILLISECONDS)); + } } }); this.bootstrap = bootstrap; @@ -131,6 +163,17 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, return this.bootstrap; } + /** + * Template method for changing properties on the given {@link SocketChannelConfig}. + *

The default implementation sets the connect timeout based on the set property. + * @param config the channel configuration + */ + protected void configureChannel(SocketChannelConfig config) { + if (this.connectTimeout >= 0) { + config.setConnectTimeoutMillis(this.connectTimeout); + } + } + @Override public void afterPropertiesSet() { getBootstrap(); -- GitLab