diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java index 2ca4e94ad..57e110b1e 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java @@ -84,6 +84,7 @@ import org.apache.hc.core5.pool.PoolEntry; import org.apache.hc.core5.pool.PoolStats; import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.ReflectionUtils; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; @@ -240,6 +241,7 @@ public T execute( } } + @SuppressWarnings("Since15") private HttpClientConnection createConnection(final Socket sock, final HttpHost targetHost) throws IOException { sock.setSoTimeout(socketConfig.getSoTimeout().toMillisecondsIntBound()); sock.setReuseAddress(socketConfig.isSoReuseAddress()); @@ -251,14 +253,16 @@ private HttpClientConnection createConnection(final Socket sock, final HttpHost if (socketConfig.getSndBufSize() > 0) { sock.setSendBufferSize(socketConfig.getSndBufSize()); } - if (this.socketConfig.getTcpKeepIdle() > 0) { - Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); - } - if (this.socketConfig.getTcpKeepInterval() > 0) { - Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); - } - if (this.socketConfig.getTcpKeepCount() > 0) { - Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + if (ReflectionUtils.supportsKeepAliveOptions()) { + if (this.socketConfig.getTcpKeepIdle() > 0) { + Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + } + if (this.socketConfig.getTcpKeepInterval() > 0) { + Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + } + if (this.socketConfig.getTcpKeepCount() > 0) { + Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + } } final int linger = socketConfig.getSoLinger().toMillisecondsIntBound(); if (linger >= 0) { diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java index 8b403389d..8a67d4ec3 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java @@ -59,6 +59,7 @@ import org.apache.hc.core5.io.Closer; import org.apache.hc.core5.io.ModalCloseable; import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.ReflectionUtils; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; @@ -139,6 +140,7 @@ public int getLocalPort() { return -1; } + @SuppressWarnings("Since15") public void start() throws IOException { if (this.status.compareAndSet(Status.READY, Status.ACTIVE)) { this.serverSocket = this.serverSocketFactory.createServerSocket( @@ -147,14 +149,16 @@ public void start() throws IOException { if (this.socketConfig.getRcvBufSize() > 0) { this.serverSocket.setReceiveBufferSize(this.socketConfig.getRcvBufSize()); } - if (this.socketConfig.getTcpKeepIdle() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); - } - if (this.socketConfig.getTcpKeepInterval() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); - } - if (this.socketConfig.getTcpKeepCount() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + if (ReflectionUtils.supportsKeepAliveOptions()) { + if (this.socketConfig.getTcpKeepIdle() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + } + if (this.socketConfig.getTcpKeepInterval() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + } + if (this.socketConfig.getTcpKeepCount() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + } } if (this.sslSetupHandler != null && this.serverSocket instanceof SSLServerSocket) { final SSLServerSocket sslServerSocket = (SSLServerSocket) this.serverSocket; diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequestListener.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequestListener.java index c2b1fd30c..9d0677197 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequestListener.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequestListener.java @@ -47,6 +47,7 @@ import org.apache.hc.core5.http.io.HttpServerConnection; import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.io.Closer; +import org.apache.hc.core5.util.ReflectionUtils; class RequestListener implements Runnable { @@ -80,6 +81,7 @@ public RequestListener( this.terminated = new AtomicBoolean(); } + @SuppressWarnings("Since15") private HttpServerConnection createConnection(final Socket socket) throws IOException { socket.setSoTimeout(this.socketConfig.getSoTimeout().toMillisecondsIntBound()); socket.setKeepAlive(this.socketConfig.isSoKeepAlive()); @@ -93,14 +95,16 @@ private HttpServerConnection createConnection(final Socket socket) throws IOExce if (this.socketConfig.getSoLinger().toSeconds() >= 0) { socket.setSoLinger(true, this.socketConfig.getSoLinger().toSecondsIntBound()); } - if (this.socketConfig.getTcpKeepIdle() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); - } - if (this.socketConfig.getTcpKeepInterval() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); - } - if (this.socketConfig.getTcpKeepCount() > 0) { - Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + if (ReflectionUtils.supportsKeepAliveOptions()) { + if (this.socketConfig.getTcpKeepIdle() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + } + if (this.socketConfig.getTcpKeepInterval() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + } + if (this.socketConfig.getTcpKeepCount() > 0) { + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + } } if (!(socket instanceof SSLSocket) && sslSocketFactory != null) { final SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, null, -1, false); diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java index 65a8f9cb7..7510c26f9 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java @@ -55,6 +55,7 @@ import org.apache.hc.core5.io.Closer; import org.apache.hc.core5.net.NamedEndpoint; import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.ReflectionUtils; import org.apache.hc.core5.util.Timeout; class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements ConnectionInitiator, IOWorkerStats { @@ -278,6 +279,7 @@ public Future connect( return sessionRequest; } + @SuppressWarnings("Since15") private void prepareSocket(final SocketChannel socketChannel) throws IOException { if (this.reactorConfig.getSndBufSize() > 0) { socketChannel.setOption(StandardSocketOptions.SO_SNDBUF, this.reactorConfig.getSndBufSize()); @@ -300,14 +302,16 @@ private void prepareSocket(final SocketChannel socketChannel) throws IOException if (this.reactorConfig.getTrafficClass() > 0) { socketChannel.setOption(StandardSocketOptions.IP_TOS, this.reactorConfig.getTrafficClass()); } - if (this.reactorConfig.getTcpKeepIdle() > 0) { - socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, this.reactorConfig.getTcpKeepIdle()); - } - if (this.reactorConfig.getTcpKeepInterval() > 0) { - socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, this.reactorConfig.getTcpKeepInterval()); - } - if (this.reactorConfig.getTcpKeepCount() > 0) { - socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, this.reactorConfig.getTcpKeepCount()); + if (ReflectionUtils.supportsKeepAliveOptions()) { + if (this.reactorConfig.getTcpKeepIdle() > 0) { + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, this.reactorConfig.getTcpKeepIdle()); + } + if (this.reactorConfig.getTcpKeepInterval() > 0) { + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, this.reactorConfig.getTcpKeepInterval()); + } + if (this.reactorConfig.getTcpKeepCount() > 0) { + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, this.reactorConfig.getTcpKeepCount()); + } } } diff --git a/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java index 749268dba..4ef59075e 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java @@ -27,12 +27,20 @@ package org.apache.hc.core5.util; -import java.lang.reflect.Method; - +import jdk.net.ExtendedSocketOptions; +import jdk.net.Sockets; import org.apache.hc.core5.annotation.Internal; +import java.lang.reflect.Method; +import java.net.Socket; +import java.util.Arrays; + @Internal +@SuppressWarnings("Since15") public final class ReflectionUtils { + private static final boolean SUPPORTS_KEEPALIVE_OPTIONS = Sockets.supportedOptions(Socket.class) + .containsAll(Arrays.asList(ExtendedSocketOptions.TCP_KEEPIDLE, ExtendedSocketOptions.TCP_KEEPINTERVAL, + ExtendedSocketOptions.TCP_KEEPCOUNT)); public static void callSetter(final Object object, final String setterName, final Class type, final Object value) { try { @@ -89,4 +97,7 @@ public static int determineJRELevel() { return 7; } + public static boolean supportsKeepAliveOptions() { + return SUPPORTS_KEEPALIVE_OPTIONS; + } }