diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncSocketTimeout.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncSocketTimeout.java index ee17bb9cf1..aae0ecb1b6 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncSocketTimeout.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncSocketTimeout.java @@ -38,7 +38,6 @@ import org.apache.hc.core5.http.Method; import org.apache.hc.core5.http.URIScheme; import org.apache.hc.core5.io.CloseMode; -import org.apache.hc.core5.util.VersionInfo; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; @@ -51,7 +50,6 @@ import static org.apache.hc.core5.util.ReflectionUtils.determineJRELevel; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.api.Assumptions.assumeTrue; abstract class AbstractTestSocketTimeout extends AbstractIntegrationTestBase { @@ -83,21 +81,26 @@ void testReadTimeouts(final int connConfigTimeout, final int responseTimeout) th } for (final boolean drip : new boolean[]{ false, true }) { - final SimpleHttpRequest request = getRequest(responseTimeout, drip, - target); - - final Throwable cause = assertThrows(ExecutionException.class, () -> client.execute(request, null).get()) - .getCause(); - assertInstanceOf(SocketTimeoutException.class, cause); + for (final boolean reuseConnection : new boolean[]{ false, true }) { + if (reuseConnection) { + client.execute(getRequest(2500, 0, false, target), null).get(); + } + final SimpleHttpRequest request = getRequest(responseTimeout, 2500, drip, target); + + final Throwable cause = assertThrows(ExecutionException.class, + () -> client.execute(request, null).get()).getCause(); + assertInstanceOf(SocketTimeoutException.class, cause, + String.format("drip=%s, reuseConnection=%s", drip, reuseConnection)); + } } closeClient(client); } - private SimpleHttpRequest getRequest(final int responseTimeout, final boolean drip, final HttpHost target) - throws Exception { + private SimpleHttpRequest getRequest(final int responseTimeout, final int delay, final boolean drip, + final HttpHost target) throws Exception { final SimpleHttpRequest request = SimpleHttpRequest.create(Method.GET, target, - "/random/10240?delay=2500&drip=" + (drip ? 1 : 0)); + "/random/10240?delay=" + delay + "&drip=" + (drip ? 1 : 0)); if (responseTimeout > 0) { request.setConfig(RequestConfig.custom() .setUnixDomainSocket(getUnixDomainSocket()) @@ -138,13 +141,6 @@ public Uds() { @Override void checkAssumptions() { assumeTrue(determineJRELevel() >= 16, "Async UDS requires Java 16+"); - final String[] components = VersionInfo - .loadVersionInfo("org.apache.hc.core5", getClass().getClassLoader()) - .getRelease() - .split("[-.]"); - final int majorVersion = Integer.parseInt(components[0]); - final int minorVersion = Integer.parseInt(components[1]); - assumeFalse(majorVersion <= 5 && minorVersion <= 3, "Async UDS requires HttpCore 5.4+"); } } } diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSocketTimeout.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSocketTimeout.java index 56bd63008e..bb8caa2aac 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSocketTimeout.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSocketTimeout.java @@ -85,15 +85,21 @@ void testReadTimeouts(final int socketConfigTimeout, final int connConfigTimeout } for (final boolean drip : new boolean[]{ false, true }) { - final HttpGet request = getRequest(responseTimeout, drip); + for (final boolean reuseConnection : new boolean[]{ false, true }) { + if (reuseConnection) { + client.execute(target, getRequest(5000, 0, false), new BasicHttpClientResponseHandler()); + } + final HttpGet request = getRequest(responseTimeout, 2500, drip); - assertThrows(SocketTimeoutException.class, () -> - client.execute(target, request, new BasicHttpClientResponseHandler())); + assertThrows(SocketTimeoutException.class, () -> + client.execute(target, request, new BasicHttpClientResponseHandler()), + String.format("drip=%s, reuseConnection=%s", drip, reuseConnection)); + } } } - private HttpGet getRequest(final int responseTimeout, final boolean drip) throws Exception { - final HttpGet request = new HttpGet(new URI("/random/10240?delay=2500&drip=" + (drip ? 1 : 0))); + private HttpGet getRequest(final int responseTimeout, final int delay, final boolean drip) throws Exception { + final HttpGet request = new HttpGet(new URI("/random/10240?delay=" + delay + "&drip=" + (drip ? 1 : 0))); if (responseTimeout > 0) { request.setConfig(RequestConfig.custom() .setUnixDomainSocket(getUnixDomainSocket()) diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java index 21c6dd9a49..5560f14392 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java @@ -260,8 +260,8 @@ private void upgradeToTls(final ManagedHttpClientConnection conn, final HttpHost socket.setSoTimeout(handshakeTimeout.toMillisecondsIntBound()); } final SSLSocket sslSocket = tlsSocketStrategy.upgrade(socket, tlsName.getHostName(), tlsName.getPort(), attachment, context); - conn.bind(sslSocket, socket); socket.setSoTimeout(soTimeout); + conn.bind(sslSocket, socket); onAfterTlsHandshake(context, endpointHost); if (LOG.isDebugEnabled()) { LOG.debug("{} {} upgraded to TLS", ConnPoolSupport.getId(conn), tlsName); @@ -283,11 +283,10 @@ private void connectToUnixDomainSocket( } final Socket newSocket = unixDomainSocketFactory.createSocket(); try { - conn.bind(newSocket); final Socket socket = unixDomainSocketFactory.connectSocket(newSocket, unixDomainSocket, connectTimeout); - conn.bind(socket); configureSocket(socket, socketConfig, false); + conn.bind(socket); onAfterSocketConnect(context, endpointHost); if (LOG.isDebugEnabled()) { LOG.debug("{} {} connected to {}", ConnPoolSupport.getId(conn), endpointHost, unixDomainSocket); diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java index f5fb1f69f4..36bd75e541 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java @@ -68,7 +68,7 @@ public class DefaultManagedHttpClientConnection private final String id; private final AtomicBoolean closed; - private Timeout socketTimeout; + private Timeout origSocketTimeout; public DefaultManagedHttpClientConnection( final String id, @@ -132,7 +132,7 @@ public void bind(final SocketHolder socketHolder) throws IOException { throw new InterruptedIOException("Connection already shutdown"); } super.bind(socketHolder); - socketTimeout = Timeout.ofMilliseconds(socketHolder.getSocket().getSoTimeout()); + origSocketTimeout = Timeout.ofMilliseconds(socketHolder.getSocket().getSoTimeout()); } @Override @@ -166,7 +166,6 @@ public void setSocketTimeout(final Timeout timeout) { LOG.debug("{} set socket timeout to {}", this.id, timeout); } super.setSocketTimeout(timeout); - socketTimeout = timeout; } @Override @@ -182,7 +181,7 @@ public void close(final CloseMode closeMode) { @Override public void bind(final Socket socket) throws IOException { super.bind(WIRE_LOG.isDebugEnabled() ? new LoggingSocketHolder(socket, this.id, WIRE_LOG) : new SocketHolder(socket)); - socketTimeout = Timeout.ofMilliseconds(socket.getSoTimeout()); + origSocketTimeout = Timeout.ofMilliseconds(socket.getSoTimeout()); } @Override @@ -190,7 +189,7 @@ public void bind(final SSLSocket sslSocket, final Socket socket) throws IOExcept super.bind(WIRE_LOG.isDebugEnabled() ? new LoggingSocketHolder(sslSocket, socket, this.id, WIRE_LOG) : new SocketHolder(sslSocket, socket)); - socketTimeout = Timeout.ofMilliseconds(sslSocket.getSoTimeout()); + origSocketTimeout = Timeout.ofMilliseconds(sslSocket.getSoTimeout()); } @Override @@ -222,7 +221,7 @@ public void passivate() { @Override public void activate() { - super.setSocketTimeout(socketTimeout); + super.setSocketTimeout(origSocketTimeout); } }