Skip to content

Commit ce82142

Browse files
committed
Fix NPE in connection evictor setup (#774)
Builders computed evictor sleep time from maxIdleTime even when only evictExpiredConnections() was enabled, causing an NPE. (cherry picked from commit bbc3ac3)
1 parent abf7489 commit ce82142

File tree

4 files changed

+31
-6
lines changed

4 files changed

+31
-6
lines changed

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ public final HttpAsyncClientBuilder evictExpiredConnections() {
866866
*/
867867
public final HttpAsyncClientBuilder evictIdleConnections(final TimeValue maxIdleTime) {
868868
this.evictIdleConnections = true;
869-
this.maxIdleTime = maxIdleTime;
869+
this.maxIdleTime = Args.notNull(maxIdleTime, "Max idle time");
870870
return this;
871871
}
872872

@@ -1146,10 +1146,11 @@ public CloseableHttpAsyncClient build() {
11461146
}
11471147
if (evictExpiredConnections || evictIdleConnections) {
11481148
if (connManagerCopy instanceof ConnPoolControl) {
1149-
TimeValue sleepTime = maxIdleTime.divide(10, TimeUnit.NANOSECONDS);
1149+
final TimeValue maxIdleTimeCopy = evictIdleConnections ? maxIdleTime : null;
1150+
TimeValue sleepTime = maxIdleTimeCopy != null ? maxIdleTimeCopy.divide(10, TimeUnit.NANOSECONDS) : ONE_SECOND;
11501151
sleepTime = sleepTime.compareTo(ONE_SECOND) < 0 ? ONE_SECOND : sleepTime;
11511152
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
1152-
sleepTime, maxIdleTime);
1153+
sleepTime, maxIdleTimeCopy);
11531154
closeablesCopy.add(connectionEvictor::shutdown);
11541155
connectionEvictor.start();
11551156
}

httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ public final HttpClientBuilder evictExpiredConnections() {
780780
*/
781781
public final HttpClientBuilder evictIdleConnections(final TimeValue maxIdleTime) {
782782
this.evictIdleConnections = true;
783-
this.maxIdleTime = maxIdleTime;
783+
this.maxIdleTime = Args.notNull(maxIdleTime, "Max idle time");
784784
return this;
785785
}
786786

@@ -1115,10 +1115,11 @@ public CloseableHttpClient build() {
11151115
}
11161116
if (evictExpiredConnections || evictIdleConnections) {
11171117
if (connManagerCopy instanceof ConnPoolControl) {
1118-
TimeValue sleepTime = maxIdleTime.divide(10, TimeUnit.NANOSECONDS);
1118+
final TimeValue maxIdleTimeCopy = evictIdleConnections ? maxIdleTime : null;
1119+
TimeValue sleepTime = maxIdleTimeCopy != null ? maxIdleTimeCopy.divide(10, TimeUnit.NANOSECONDS) : ONE_SECOND;
11191120
sleepTime = sleepTime.compareTo(ONE_SECOND) < 0 ? ONE_SECOND : sleepTime;
11201121
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
1121-
sleepTime, maxIdleTime);
1122+
sleepTime, maxIdleTimeCopy);
11221123
closeablesCopy.add(() -> {
11231124
connectionEvictor.shutdown();
11241125
try {

httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpAsyncClientBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131
import org.apache.hc.client5.http.async.AsyncExecCallback;
3232
import org.apache.hc.client5.http.async.AsyncExecChain;
3333
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
34+
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
35+
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
3436
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
3537
import org.apache.hc.core5.http.HttpException;
3638
import org.apache.hc.core5.http.HttpRequest;
3739
import org.apache.hc.core5.http.nio.AsyncEntityProducer;
40+
import org.junit.jupiter.api.Assertions;
3841
import org.junit.jupiter.api.Test;
3942

4043
class TestHttpAsyncClientBuilder {
@@ -82,4 +85,14 @@ public void execute(final HttpRequest request, final AsyncEntityProducer entityP
8285
chain.proceed(request, entityProducer, scope, asyncExecCallback);
8386
}
8487
}
88+
89+
90+
@Test
91+
void testEvictExpiredConnectionsDoesNotRequireMaxIdleTime() throws Exception {
92+
try (final CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create()
93+
.evictExpiredConnections()
94+
.build()) {
95+
Assertions.assertNotNull(client);
96+
}
97+
}
8598
}

httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpClientBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.hc.core5.http.ClassicHttpRequest;
3434
import org.apache.hc.core5.http.ClassicHttpResponse;
3535
import org.apache.hc.core5.http.HttpException;
36+
import org.junit.jupiter.api.Assertions;
3637
import org.junit.jupiter.api.Test;
3738

3839
class TestHttpClientBuilder {
@@ -66,4 +67,13 @@ public ClassicHttpResponse execute(
6667
return chain.proceed(request, scope);
6768
}
6869
}
70+
71+
@Test
72+
void testEvictExpiredConnectionsDoesNotRequireMaxIdleTime() throws Exception {
73+
try (final CloseableHttpClient client = HttpClientBuilder.create()
74+
.evictExpiredConnections()
75+
.build()) {
76+
Assertions.assertNotNull(client);
77+
}
78+
}
6979
}

0 commit comments

Comments
 (0)