Replaced socket and connect timeout request parameters with a single connection timeout request parameter. HTTP requests may be executed concurrently over a single HTTP/2 connection and no longer should overwrite connection socket timeout

This commit is contained in:
Oleg Kalnichevski 2017-11-18 11:24:17 +01:00
parent 47dfbfa221
commit 235348eec6
21 changed files with 53 additions and 114 deletions

View File

@ -52,9 +52,7 @@ public class FluentExecutor {
// Execute a GET with timeout settings and return response content as String.
executor.execute(Request.Get("http://somehost/")
.connectTimeout(Timeout.ofSeconds(1))
.socketTimeout(Timeout.ofSeconds(1))
).returnContent().asString();
.connectionTimeout(Timeout.ofSeconds(1))).returnContent().asString();
// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,
// containing a request body as String and return response content as byte array.

View File

@ -43,8 +43,7 @@ public class FluentRequests {
public static void main(String[] args)throws Exception {
// Execute a GET with timeout settings and return response content as String.
Request.Get("http://somehost/")
.connectTimeout(Timeout.ofSeconds(1))
.socketTimeout(Timeout.ofSeconds(1))
.connectionTimeout(Timeout.ofSeconds(1))
.execute().returnContent().asString();
// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,

View File

@ -76,8 +76,7 @@ public class Request {
private final HttpUriRequestBase request;
private Boolean useExpectContinue;
private Timeout socketTmeout;
private Timeout connectTimeout;
private Timeout connectionTimeout;
private HttpHost proxy;
private SimpleDateFormat dateFormatter;
@ -171,11 +170,8 @@ public class Request {
if (this.useExpectContinue != null) {
builder.setExpectContinueEnabled(this.useExpectContinue);
}
if (this.socketTmeout != null) {
builder.setSocketTimeout(this.socketTmeout);
}
if (this.connectTimeout != null) {
builder.setConnectTimeout(this.connectTimeout);
if (this.connectionTimeout != null) {
builder.setConnectionTimeout(this.connectionTimeout);
}
if (this.proxy != null) {
builder.setProxy(this.proxy);
@ -283,13 +279,8 @@ public class Request {
//// HTTP connection parameter operations
public Request socketTimeout(final Timeout timeout) {
this.socketTmeout = timeout;
return this;
}
public Request connectTimeout(final Timeout timeout) {
this.connectTimeout = timeout;
public Request connectionTimeout(final Timeout timeout) {
this.connectionTimeout = timeout;
return this;
}

View File

@ -90,8 +90,7 @@ public abstract class AbstractHttp1IntegrationTestBase extends AbstractServerTes
protected void before() throws Throwable {
clientBuilder = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -94,8 +94,7 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
protected void before() throws Throwable {
clientBuilder = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -111,8 +111,7 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
protected void before() throws Throwable {
clientBuilder = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -89,8 +89,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
protected void before() throws Throwable {
clientBuilder = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -106,8 +106,7 @@ public class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthen
protected void before() throws Throwable {
clientBuilder = HttpAsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -62,8 +62,7 @@ public class TestHttp2Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
protected void before() throws Throwable {
clientBuilder = Http2AsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setTlsStrategy(new BasicClientTlsStrategy(SSLTestContexts.createClientSSLContext()));

View File

@ -62,8 +62,7 @@ public class TestHttp2AsyncRedirect extends AbstractHttpAsyncRedirectsTest<Close
protected void before() throws Throwable {
clientBuilder = Http2AsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setTlsStrategy(new H2TlsStrategy(SSLTestContexts.createClientSSLContext()));

View File

@ -66,8 +66,7 @@ public class TestHttp2ClientAuthentication extends AbstractHttpAsyncClientAuthen
protected void before() throws Throwable {
clientBuilder = Http2AsyncClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setTlsStrategy(new H2TlsStrategy(SSLTestContexts.createClientSSLContext()));

View File

@ -110,8 +110,7 @@ public abstract class LocalServerTestBase {
.build());
clientBuilder = HttpClientBuilder.create()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setConnectionTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build())
.setConnectionManager(connManager);

View File

@ -212,8 +212,7 @@ public class ClientConfiguration {
// Request configuration can be overridden at the request level.
// They will take precedence over the one set at the client level.
final RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
.setSocketTimeout(Timeout.ofSeconds(5))
.setConnectTimeout(Timeout.ofSeconds(5))
.setConnectionTimeout(Timeout.ofSeconds(5))
.setConnectionRequestTimeout(Timeout.ofSeconds(5))
.setProxy(new HttpHost("myotherproxy", 8080))
.build();

View File

@ -42,8 +42,7 @@ import org.apache.hc.core5.util.Timeout;
public class RequestConfig implements Cloneable {
private static final Timeout DEFAULT_CONNECTION_REQUEST_TIMEOUT = Timeout.ofMinutes(3);
private static final Timeout DEFAULT_CONNECT_TIMEOUT = Timeout.ofMinutes(3);
private static final Timeout DEFAULT_SOCKET_TIMEOUT = Timeout.ZERO_MILLISECONDS;
private static final Timeout DEFAULT_CONNECTION_TIMEOUT = Timeout.ofMinutes(3);
public static final RequestConfig DEFAULT = new Builder().build();
@ -57,16 +56,14 @@ public class RequestConfig implements Cloneable {
private final Collection<String> targetPreferredAuthSchemes;
private final Collection<String> proxyPreferredAuthSchemes;
private final Timeout connectionRequestTimeout;
private final Timeout connectTimeout;
private final Timeout socketTimeout;
private final Timeout connectionTimeout;
private final boolean contentCompressionEnabled;
/**
* Intended for CDI compatibility
*/
protected RequestConfig() {
this(false, null, null, false, false, 0, false, null, null,
DEFAULT_CONNECTION_REQUEST_TIMEOUT, DEFAULT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT, false);
this(false, null, null, false, false, 0, false, null, null, DEFAULT_CONNECTION_REQUEST_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT, false);
}
RequestConfig(
@ -80,8 +77,7 @@ public class RequestConfig implements Cloneable {
final Collection<String> targetPreferredAuthSchemes,
final Collection<String> proxyPreferredAuthSchemes,
final Timeout connectionRequestTimeout,
final Timeout connectTimeout,
final Timeout socketTimeout,
final Timeout connectionTimeout,
final boolean contentCompressionEnabled) {
super();
this.expectContinueEnabled = expectContinueEnabled;
@ -94,8 +90,7 @@ public class RequestConfig implements Cloneable {
this.targetPreferredAuthSchemes = targetPreferredAuthSchemes;
this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes;
this.connectionRequestTimeout = connectionRequestTimeout;
this.connectTimeout = connectTimeout;
this.socketTimeout = socketTimeout;
this.connectionTimeout = connectionTimeout;
this.contentCompressionEnabled = contentCompressionEnabled;
}
@ -228,7 +223,8 @@ public class RequestConfig implements Cloneable {
}
/**
* Determines the timeout in milliseconds until a connection is established.
* Determines the timeout in milliseconds until a new connection is
* fully established or established connection transmits a data packet.
* A timeout value of zero is interpreted as an infinite timeout.
* <p>
* A timeout value of zero is interpreted as an infinite timeout.
@ -237,25 +233,11 @@ public class RequestConfig implements Cloneable {
* <p>
* Default: 3 minutes
* </p>
*
* @since 5.0
*/
public Timeout getConnectTimeout() {
return connectTimeout;
}
/**
* Defines the socket timeout ({@code SO_TIMEOUT}) in milliseconds,
* which is the timeout for waiting for data or, put differently,
* a maximum period inactivity between two consecutive data packets).
* <p>
* A timeout value of zero is interpreted as an infinite timeout.
* A negative value is interpreted as undefined (system default).
* </p>
* <p>
* Default: no timeout.
* </p>
*/
public Timeout getSocketTimeout() {
return socketTimeout;
public Timeout getConnectionTimeout() {
return connectionTimeout;
}
/**
@ -289,8 +271,7 @@ public class RequestConfig implements Cloneable {
builder.append(", targetPreferredAuthSchemes=").append(targetPreferredAuthSchemes);
builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes);
builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout);
builder.append(", connectTimeout=").append(connectTimeout);
builder.append(", socketTimeout=").append(socketTimeout);
builder.append(", connectionTimeout=").append(connectionTimeout);
builder.append(", contentCompressionEnabled=").append(contentCompressionEnabled);
builder.append("]");
return builder.toString();
@ -312,8 +293,7 @@ public class RequestConfig implements Cloneable {
.setTargetPreferredAuthSchemes(config.getTargetPreferredAuthSchemes())
.setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes())
.setConnectionRequestTimeout(config.getConnectionRequestTimeout())
.setConnectTimeout(config.getConnectTimeout())
.setSocketTimeout(config.getSocketTimeout())
.setConnectionTimeout(config.getConnectionTimeout())
.setContentCompressionEnabled(config.isContentCompressionEnabled());
}
@ -329,8 +309,7 @@ public class RequestConfig implements Cloneable {
private Collection<String> targetPreferredAuthSchemes;
private Collection<String> proxyPreferredAuthSchemes;
private Timeout connectionRequestTimeout;
private Timeout connectTimeout;
private Timeout socketTimeout;
private Timeout connectionTimeout;
private boolean contentCompressionEnabled;
Builder() {
@ -339,8 +318,7 @@ public class RequestConfig implements Cloneable {
this.maxRedirects = 50;
this.authenticationEnabled = true;
this.connectionRequestTimeout = DEFAULT_CONNECTION_REQUEST_TIMEOUT;
this.connectTimeout = DEFAULT_CONNECT_TIMEOUT;
this.socketTimeout = DEFAULT_SOCKET_TIMEOUT;
this.connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
this.contentCompressionEnabled = true;
}
@ -399,23 +377,13 @@ public class RequestConfig implements Cloneable {
return this;
}
public Builder setConnectTimeout(final Timeout connectTimeout) {
this.connectTimeout = connectTimeout;
public Builder setConnectionTimeout(final Timeout connectionTimeout) {
this.connectionTimeout = connectionTimeout;
return this;
}
public Builder setConnectTimeout(final long connectTimeout, final TimeUnit timeUnit) {
this.connectTimeout = Timeout.of(connectTimeout, timeUnit);
return this;
}
public Builder setSocketTimeout(final Timeout socketTimeout) {
this.socketTimeout = socketTimeout;
return this;
}
public Builder setSocketTimeout(final long socketTimeout, final TimeUnit timeUnit) {
this.socketTimeout = Timeout.of(socketTimeout, timeUnit);
this.connectionTimeout = Timeout.of(connectTimeout, timeUnit);
return this;
}
@ -436,8 +404,7 @@ public class RequestConfig implements Cloneable {
targetPreferredAuthSchemes,
proxyPreferredAuthSchemes,
connectionRequestTimeout != null ? connectionRequestTimeout : DEFAULT_CONNECTION_REQUEST_TIMEOUT,
connectTimeout != null ? connectTimeout : DEFAULT_CONNECT_TIMEOUT,
socketTimeout != null ? socketTimeout : DEFAULT_SOCKET_TIMEOUT,
connectionTimeout != null ? connectionTimeout : DEFAULT_CONNECTION_TIMEOUT,
contentCompressionEnabled);
}

View File

@ -73,7 +73,7 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
if (sessionRef.get() == null) {
final HttpHost target = route.getTargetHost();
final RequestConfig requestConfig = context.getRequestConfig();
connPool.getSession(target, requestConfig.getConnectTimeout(), new FutureCallback<IOSession>() {
connPool.getSession(target, requestConfig.getConnectionTimeout(), new FutureCallback<IOSession>() {
@Override
public void completed(final IOSession ioSession) {
@ -153,7 +153,7 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
} else {
final HttpHost target = endpoint.target;
final RequestConfig requestConfig = context.getRequestConfig();
connPool.getSession(target, requestConfig.getConnectTimeout(), new FutureCallback<IOSession>() {
connPool.getSession(target, requestConfig.getConnectionTimeout(), new FutureCallback<IOSession>() {
@Override
public void completed(final IOSession ioSession) {
@ -194,7 +194,7 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
} else {
final HttpHost target = endpoint.target;
final RequestConfig requestConfig = context.getRequestConfig();
connPool.getSession(target, requestConfig.getConnectTimeout(), new FutureCallback<IOSession>() {
connPool.getSession(target, requestConfig.getConnectionTimeout(), new FutureCallback<IOSession>() {
@Override
public void completed(final IOSession ioSession) {

View File

@ -183,19 +183,19 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
callback.completed(this);
} else {
final RequestConfig requestConfig = context.getRequestConfig();
final TimeValue timeout = requestConfig.getConnectionTimeout();
manager.connect(
endpoint,
connectionInitiator,
requestConfig.getConnectTimeout(),
timeout,
versionPolicy,
context,
new FutureCallback<AsyncConnectionEndpoint>() {
@Override
public void completed(final AsyncConnectionEndpoint endpoint) {
final TimeValue socketTimeout = requestConfig.getSocketTimeout();
if (TimeValue.isPositive(socketTimeout)) {
endpoint.setSocketTimeout(socketTimeout.toMillisIntBound());
if (TimeValue.isPositive(timeout)) {
endpoint.setSocketTimeout(timeout.toMillisIntBound());
}
callback.completed(InternalHttpAsyncExecRuntime.this);
}

View File

@ -133,7 +133,7 @@ public final class MinimalHttp2AsyncClient extends AbstractMinimalHttpAsyncClien
} else {
requestConfig = clientContext.getRequestConfig();
}
final Timeout connectTimeout = requestConfig.getConnectTimeout();
final Timeout connectTimeout = requestConfig.getConnectionTimeout();
final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
final Future<IOSession> sessionFuture = connPool.getSession(target, connectTimeout, new FutureCallback<IOSession>() {

View File

@ -180,7 +180,7 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
final HttpClientContext clientContext = HttpClientContext.adapt(context);
final RequestConfig requestConfig = clientContext.getRequestConfig();
final BasicFuture<AsyncClientEndpoint> future = new BasicFuture<>(callback);
leaseEndpoint(host, requestConfig.getConnectTimeout(), clientContext, new FutureCallback<AsyncConnectionEndpoint>() {
leaseEndpoint(host, requestConfig.getConnectionTimeout(), clientContext, new FutureCallback<AsyncConnectionEndpoint>() {
@Override
public void completed(final AsyncConnectionEndpoint result) {
@ -225,7 +225,7 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
} else {
requestConfig = clientContext.getRequestConfig();
}
final Timeout connectTimeout = requestConfig.getConnectTimeout();
final Timeout connectTimeout = requestConfig.getConnectionTimeout();
final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(target, connectTimeout, clientContext,

View File

@ -149,11 +149,10 @@ class ExecRuntimeImpl implements ExecRuntime, Cancellable {
}
}
final RequestConfig requestConfig = context.getRequestConfig();
final TimeValue connectTimeout = requestConfig.getConnectTimeout();
manager.connect(endpoint, connectTimeout, context);
final TimeValue socketTimeout = requestConfig.getSocketTimeout();
if (socketTimeout.getDuration() >= 0) {
endpoint.setSocketTimeout(socketTimeout.toMillisIntBound());
final TimeValue timeout = requestConfig.getConnectionTimeout();
manager.connect(endpoint, timeout, context);
if (TimeValue.isPositive(timeout)) {
endpoint.setSocketTimeout(timeout.toMillisIntBound());
}
}

View File

@ -47,8 +47,7 @@ public class TestRequestConfig {
@Test
public void testDefaults() {
final RequestConfig config = RequestConfig.DEFAULT;
Assert.assertEquals(Timeout.ZERO_MILLISECONDS, config.getSocketTimeout());
Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectTimeout());
Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectionTimeout());
Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectionRequestTimeout());
Assert.assertEquals(false, config.isExpectContinueEnabled());
Assert.assertEquals(true, config.isAuthenticationEnabled());
@ -65,7 +64,6 @@ public class TestRequestConfig {
@Test
public void testBuildAndCopy() throws Exception {
final RequestConfig config0 = RequestConfig.custom()
.setSocketTimeout(22, TimeUnit.MILLISECONDS)
.setConnectTimeout(33, TimeUnit.MILLISECONDS)
.setConnectionRequestTimeout(44, TimeUnit.MILLISECONDS)
.setExpectContinueEnabled(true)
@ -80,8 +78,7 @@ public class TestRequestConfig {
.setContentCompressionEnabled(false)
.build();
final RequestConfig config = RequestConfig.copy(config0).build();
Assert.assertEquals(TimeValue.ofMillis(22), config.getSocketTimeout());
Assert.assertEquals(TimeValue.ofMillis(33), config.getConnectTimeout());
Assert.assertEquals(TimeValue.ofMillis(33), config.getConnectionTimeout());
Assert.assertEquals(TimeValue.ofMillis(44), config.getConnectionRequestTimeout());
Assert.assertEquals(true, config.isExpectContinueEnabled());
Assert.assertEquals(false, config.isAuthenticationEnabled());

View File

@ -83,7 +83,6 @@ public class TestExecRuntimeImpl {
final HttpClientContext context = HttpClientContext.create();
final RequestConfig config = RequestConfig.custom()
.setConnectTimeout(123, TimeUnit.MILLISECONDS)
.setSocketTimeout(234, TimeUnit.MILLISECONDS)
.setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
.build();
context.setRequestConfig(config);
@ -261,7 +260,6 @@ public class TestExecRuntimeImpl {
final HttpClientContext context = HttpClientContext.create();
final RequestConfig config = RequestConfig.custom()
.setConnectTimeout(123, TimeUnit.MILLISECONDS)
.setSocketTimeout(234, TimeUnit.MILLISECONDS)
.setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
.build();
context.setRequestConfig(config);
@ -279,7 +277,7 @@ public class TestExecRuntimeImpl {
execRuntime.connect(context);
Mockito.verify(mgr).connect(connectionEndpoint, TimeValue.ofMillis(123), context);
Mockito.verify(connectionEndpoint).setSocketTimeout(234);
Mockito.verify(connectionEndpoint).setSocketTimeout(123);
}
@Test