Use finite (3 minutes) connection keep-alive period by default

This commit is contained in:
Oleg Kalnichevski 2020-02-14 10:32:53 +01:00
parent 85eec39f7f
commit 42cae6999c
3 changed files with 66 additions and 6 deletions

View File

@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
/**
@ -43,6 +44,7 @@ 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 TimeValue DEFAULT_CONN_KEEP_ALIVE = TimeValue.ofMinutes(3);
public static final RequestConfig DEFAULT = new Builder().build();
@ -58,6 +60,7 @@ public class RequestConfig implements Cloneable {
private final Timeout connectionRequestTimeout;
private final Timeout connectTimeout;
private final Timeout responseTimeout;
private final TimeValue connectionKeepAlive;
private final boolean contentCompressionEnabled;
private final boolean hardCancellationEnabled;
@ -66,7 +69,7 @@ public class RequestConfig implements Cloneable {
*/
protected RequestConfig() {
this(false, null, null, false, false, 0, false, null, null,
DEFAULT_CONNECTION_REQUEST_TIMEOUT, DEFAULT_CONNECT_TIMEOUT, null, false, false);
DEFAULT_CONNECTION_REQUEST_TIMEOUT, DEFAULT_CONNECT_TIMEOUT, null, DEFAULT_CONN_KEEP_ALIVE, false, false);
}
RequestConfig(
@ -82,6 +85,7 @@ public class RequestConfig implements Cloneable {
final Timeout connectionRequestTimeout,
final Timeout connectTimeout,
final Timeout responseTimeout,
final TimeValue connectionKeepAlive,
final boolean contentCompressionEnabled,
final boolean hardCancellationEnabled) {
super();
@ -97,6 +101,7 @@ public class RequestConfig implements Cloneable {
this.connectionRequestTimeout = connectionRequestTimeout;
this.connectTimeout = connectTimeout;
this.responseTimeout = responseTimeout;
this.connectionKeepAlive = connectionKeepAlive;
this.contentCompressionEnabled = contentCompressionEnabled;
this.hardCancellationEnabled = hardCancellationEnabled;
}
@ -185,6 +190,13 @@ public class RequestConfig implements Cloneable {
return responseTimeout;
}
/**
* @see Builder#setConnectionKeepAlive(TimeValue)
*/
public TimeValue getConnectionKeepAlive() {
return connectionKeepAlive;
}
/**
* @see Builder#setContentCompressionEnabled(boolean)
*/
@ -219,6 +231,7 @@ public class RequestConfig implements Cloneable {
builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes);
builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout);
builder.append(", connectTimeout=").append(connectTimeout);
builder.append(", connectionKeepAlive=").append(connectionKeepAlive);
builder.append(", contentCompressionEnabled=").append(contentCompressionEnabled);
builder.append(", hardCancellationEnabled=").append(hardCancellationEnabled);
builder.append("]");
@ -242,6 +255,7 @@ public class RequestConfig implements Cloneable {
.setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes())
.setConnectionRequestTimeout(config.getConnectionRequestTimeout())
.setConnectTimeout(config.getConnectTimeout())
.setConnectionKeepAlive(config.getConnectionKeepAlive())
.setContentCompressionEnabled(config.isContentCompressionEnabled())
.setHardCancellationEnabled(config.isHardCancellationEnabled());
}
@ -260,6 +274,7 @@ public class RequestConfig implements Cloneable {
private Timeout connectionRequestTimeout;
private Timeout connectTimeout;
private Timeout responseTimeout;
private TimeValue connectionKeepAlive;
private boolean contentCompressionEnabled;
private boolean hardCancellationEnabled;
@ -470,6 +485,32 @@ public class RequestConfig implements Cloneable {
return this;
}
/**
* Determines the default of value of connection keep-alive time period when not
* explicitly communicated by the origin server with a {@code Keep-Alive} response
* header.
* <p>
* A negative value is interpreted as an infinite keep-alive period.
* </p>
* <p>
* Default: 1 minute
* </p>
*
* @since 5.0
*/
public Builder setConnectionKeepAlive(final TimeValue connectionKeepAlive) {
this.connectionKeepAlive = connectionKeepAlive;
return this;
}
/**
* @see #setConnectionKeepAlive(TimeValue)
*/
public Builder setDefaultKeepAlive(final long defaultKeepAlive, final TimeUnit timeUnit) {
this.connectionKeepAlive = TimeValue.of(defaultKeepAlive, timeUnit);
return this;
}
/**
* Determines whether the target server is requested to compress content.
* <p>
@ -529,6 +570,7 @@ public class RequestConfig implements Cloneable {
connectionRequestTimeout != null ? connectionRequestTimeout : DEFAULT_CONNECTION_REQUEST_TIMEOUT,
connectTimeout != null ? connectTimeout : DEFAULT_CONNECT_TIMEOUT,
responseTimeout,
connectionKeepAlive != null ? connectionKeepAlive : DEFAULT_CONN_KEEP_ALIVE,
contentCompressionEnabled,
hardCancellationEnabled);
}

View File

@ -29,6 +29,8 @@ package org.apache.hc.client5.http.impl;
import java.util.Iterator;
import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HeaderElement;
@ -69,7 +71,9 @@ public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveSt
}
}
}
return TimeValue.NEG_ONE_MILLISECOND;
final HttpClientContext clientContext = HttpClientContext.adapt(context);
final RequestConfig requestConfig = clientContext.getRequestConfig();
return requestConfig.getConnectionKeepAlive();
}
}

View File

@ -27,6 +27,8 @@
package org.apache.hc.client5.http.impl;
import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.message.BasicHttpResponse;
@ -50,7 +52,10 @@ public class TestDefaultConnKeepAliveStrategy {
@Test
public void testNoKeepAliveHeader() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final HttpClientContext context = HttpClientContext.create();
context.setRequestConfig( RequestConfig.custom()
.setConnectionKeepAlive(TimeValue.NEG_ONE_MILLISECOND)
.build());
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy();
final TimeValue d = keepAliveStrat.getKeepAliveDuration(response, context);
@ -59,7 +64,10 @@ public class TestDefaultConnKeepAliveStrategy {
@Test
public void testEmptyKeepAliveHeader() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final HttpClientContext context = HttpClientContext.create();
context.setRequestConfig( RequestConfig.custom()
.setConnectionKeepAlive(TimeValue.NEG_ONE_MILLISECOND)
.build());
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
response.addHeader("Keep-Alive", "timeout, max=20");
final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy();
@ -69,7 +77,10 @@ public class TestDefaultConnKeepAliveStrategy {
@Test
public void testInvalidKeepAliveHeader() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final HttpClientContext context = HttpClientContext.create();
context.setRequestConfig( RequestConfig.custom()
.setConnectionKeepAlive(TimeValue.NEG_ONE_MILLISECOND)
.build());
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
response.addHeader("Keep-Alive", "timeout=whatever, max=20");
final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy();
@ -79,7 +90,10 @@ public class TestDefaultConnKeepAliveStrategy {
@Test
public void testKeepAliveHeader() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final HttpClientContext context = HttpClientContext.create();
context.setRequestConfig( RequestConfig.custom()
.setConnectionKeepAlive(TimeValue.NEG_ONE_MILLISECOND)
.build());
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
response.addHeader("Keep-Alive", "timeout=300, max=20");
final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy();