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 d9ed1b08b1..2ca4e94ad7 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 @@ -45,6 +45,8 @@ import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import jdk.net.ExtendedSocketOptions; +import jdk.net.Sockets; import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.function.Callback; import org.apache.hc.core5.function.Resolver; @@ -76,7 +78,6 @@ import org.apache.hc.core5.io.CloseMode; import org.apache.hc.core5.io.Closer; import org.apache.hc.core5.io.ModalCloseable; -import org.apache.hc.core5.io.SocketSupport; import org.apache.hc.core5.net.URIAuthority; import org.apache.hc.core5.pool.ConnPoolControl; import org.apache.hc.core5.pool.ManagedConnPool; @@ -251,13 +252,13 @@ private HttpClientConnection createConnection(final Socket sock, final HttpHost sock.setSendBufferSize(socketConfig.getSndBufSize()); } if (this.socketConfig.getTcpKeepIdle() > 0) { - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); } if (this.socketConfig.getTcpKeepInterval() > 0) { - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + Sockets.setOption(sock, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); } if (this.socketConfig.getTcpKeepCount() > 0) { - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + 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 5a8deaa2d7..8b403389df 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 @@ -41,6 +41,8 @@ import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; +import jdk.net.ExtendedSocketOptions; +import jdk.net.Sockets; import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.concurrent.DefaultThreadFactory; import org.apache.hc.core5.function.Callback; @@ -56,7 +58,6 @@ import org.apache.hc.core5.io.CloseMode; import org.apache.hc.core5.io.Closer; import org.apache.hc.core5.io.ModalCloseable; -import org.apache.hc.core5.io.SocketSupport; import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; @@ -147,13 +148,13 @@ public void start() throws IOException { this.serverSocket.setReceiveBufferSize(this.socketConfig.getRcvBufSize()); } if (this.socketConfig.getTcpKeepIdle() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); } if (this.socketConfig.getTcpKeepInterval() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); } if (this.socketConfig.getTcpKeepCount() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + 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 1c58748a94..c2b1fd30c9 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 @@ -38,6 +38,8 @@ import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import jdk.net.ExtendedSocketOptions; +import jdk.net.Sockets; import org.apache.hc.core5.function.Callback; import org.apache.hc.core5.http.ExceptionListener; import org.apache.hc.core5.http.impl.io.HttpService; @@ -45,7 +47,6 @@ 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.io.SocketSupport; class RequestListener implements Runnable { @@ -93,13 +94,13 @@ private HttpServerConnection createConnection(final Socket socket) throws IOExce socket.setSoLinger(true, this.socketConfig.getSoLinger().toSecondsIntBound()); } if (this.socketConfig.getTcpKeepIdle() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPIDLE, this.socketConfig.getTcpKeepIdle()); } if (this.socketConfig.getTcpKeepInterval() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); + Sockets.setOption(this.serverSocket, ExtendedSocketOptions.TCP_KEEPINTERVAL, this.socketConfig.getTcpKeepInterval()); } if (this.socketConfig.getTcpKeepCount() > 0) { - SocketSupport.setOption(this.serverSocket, SocketSupport.TCP_KEEPCOUNT, this.socketConfig.getTcpKeepCount()); + 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/io/SocketSupport.java b/httpcore5/src/main/java/org/apache/hc/core5/io/SocketSupport.java deleted file mode 100644 index aaf6d8cbd7..0000000000 --- a/httpcore5/src/main/java/org/apache/hc/core5/io/SocketSupport.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.apache.hc.core5.io; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.SocketOption; - -import org.apache.hc.core5.annotation.Internal; - -/** - * @since 5.3 - */ -@Internal -public class SocketSupport { - - public static final String TCP_KEEPIDLE = "TCP_KEEPIDLE"; - public static final String TCP_KEEPINTERVAL = "TCP_KEEPINTERVAL"; - public static final String TCP_KEEPCOUNT = "TCP_KEEPCOUNT"; - - @SuppressWarnings("unchecked") - public static SocketOption getExtendedSocketOptionOrNull(final String fieldName) { - try { - final Class extendedSocketOptionsClass = Class.forName("jdk.net.ExtendedSocketOptions"); - final Field field = extendedSocketOptionsClass.getField(fieldName); - return (SocketOption) field.get(null); - } catch (final Exception ignore) { - return null; - } - } - - /** - * Object can be ServerSocket or Socket. - * - * @param ServerSocket or Socket. - * @throws IOException in case of an I/O error. - */ - public static void setOption(final T object, final String fieldName, final T value) throws IOException { - try { - final Class serverSocketClass = object.getClass(); - final Method setOptionMethod = serverSocketClass.getMethod("setOption", SocketOption.class, Object.class); - final SocketOption socketOption = getExtendedSocketOptionOrNull(fieldName); - if (socketOption == null) { - throw new UnsupportedOperationException("Extended socket option not supported: " + fieldName); - } - setOptionMethod.invoke(object, socketOption, value); - } catch (final UnsupportedOperationException e) { - throw e; - } catch (final Exception ex) { - throw new IOException("Failure setting extended socket option", ex); - } - } - -} 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 9bd64ca026..65a8f9cb7c 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 @@ -32,7 +32,6 @@ import java.net.ProtocolFamily; import java.net.Socket; import java.net.SocketAddress; -import java.net.SocketOption; import java.net.StandardProtocolFamily; import java.net.StandardSocketOptions; import java.net.UnknownHostException; @@ -48,12 +47,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import jdk.net.ExtendedSocketOptions; import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.function.Callback; import org.apache.hc.core5.function.Decorator; import org.apache.hc.core5.io.CloseMode; import org.apache.hc.core5.io.Closer; -import org.apache.hc.core5.io.SocketSupport; import org.apache.hc.core5.net.NamedEndpoint; import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.Timeout; @@ -302,28 +301,16 @@ private void prepareSocket(final SocketChannel socketChannel) throws IOException socketChannel.setOption(StandardSocketOptions.IP_TOS, this.reactorConfig.getTrafficClass()); } if (this.reactorConfig.getTcpKeepIdle() > 0) { - setExtendedSocketOption(socketChannel, SocketSupport.TCP_KEEPIDLE, this.reactorConfig.getTcpKeepIdle()); + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, this.reactorConfig.getTcpKeepIdle()); } if (this.reactorConfig.getTcpKeepInterval() > 0) { - setExtendedSocketOption(socketChannel, SocketSupport.TCP_KEEPINTERVAL, this.reactorConfig.getTcpKeepInterval()); + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, this.reactorConfig.getTcpKeepInterval()); } if (this.reactorConfig.getTcpKeepCount() > 0) { - setExtendedSocketOption(socketChannel, SocketSupport.TCP_KEEPCOUNT, this.reactorConfig.getTcpKeepCount()); + socketChannel.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, this.reactorConfig.getTcpKeepCount()); } } - /** - * @since 5.3 - */ - void setExtendedSocketOption(final SocketChannel socketChannel, - final String optionName, final T value) throws IOException { - final SocketOption socketOption = SocketSupport.getExtendedSocketOptionOrNull(optionName); - if (socketOption == null) { - throw new UnsupportedOperationException(optionName + " is not supported in the current jdk"); - } - socketChannel.setOption(socketOption, value); - } - private void validateAddress(final SocketAddress address) throws UnknownHostException { if (address instanceof InetSocketAddress) { final InetSocketAddress endpoint = (InetSocketAddress) address; diff --git a/httpcore5/src/test/java/org/apache/hc/core5/io/TestSocketSupport.java b/httpcore5/src/test/java/org/apache/hc/core5/io/TestSocketSupport.java deleted file mode 100644 index e0fd691638..0000000000 --- a/httpcore5/src/test/java/org/apache/hc/core5/io/TestSocketSupport.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.apache.hc.core5.io; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketOption; - -import javax.net.ServerSocketFactory; - -import org.apache.hc.core5.util.ReflectionUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class TestSocketSupport { - - @Test - void testGetExtendedSocketOptionOrNull() { - testGetExtendedSocketOption(SocketSupport.TCP_KEEPIDLE); - testGetExtendedSocketOption(SocketSupport.TCP_KEEPINTERVAL); - testGetExtendedSocketOption(SocketSupport.TCP_KEEPCOUNT); - } - - private void testGetExtendedSocketOption(final String option) { - final SocketOption socketOption = SocketSupport.getExtendedSocketOptionOrNull(option); - // 1.Partial versions of jdk1.8 contain TCP_KEEPIDLE, TCP_KEEPINTERVAL, TCP_KEEPCOUNT. - // 2. Windows may not support TCP_KEEPIDLE, TCP_KEEPINTERVAL, TCP_KEEPCOUNT. - if (ReflectionUtils.determineJRELevel() > 8 && !isWindows()) { - Assertions.assertNotNull(socketOption); - } - } - - @Test - void testSetOption() throws IOException { - if (ReflectionUtils.determineJRELevel() > 8 && isWindows() == false) { - { - // test Socket - final Socket sock = new Socket(); - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPIDLE, 20); - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPINTERVAL, 21); - SocketSupport.setOption(sock, SocketSupport.TCP_KEEPCOUNT, 22); - - final SocketOption tcpKeepIdle = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPIDLE); - assert tcpKeepIdle != null; - Assertions.assertEquals(20, ReflectionUtils.callGetter(sock, "Option", tcpKeepIdle, SocketOption.class, Integer.class)); - - final SocketOption tcpKeepInterval = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPINTERVAL); - assert tcpKeepInterval != null; - Assertions.assertEquals(21, ReflectionUtils.callGetter(sock, "Option", tcpKeepInterval, SocketOption.class, Integer.class)); - - final SocketOption tcpKeepCount = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPCOUNT); - assert tcpKeepCount != null; - Assertions.assertEquals(22, ReflectionUtils.callGetter(sock, "Option", tcpKeepCount, SocketOption.class, Integer.class)); - } - - { - // test ServerSocket - final ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(); - SocketSupport.setOption(serverSocket, SocketSupport.TCP_KEEPIDLE, 20); - SocketSupport.setOption(serverSocket, SocketSupport.TCP_KEEPINTERVAL, 21); - SocketSupport.setOption(serverSocket, SocketSupport.TCP_KEEPCOUNT, 22); - - final SocketOption tcpKeepIdle = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPIDLE); - assert tcpKeepIdle != null; - Assertions.assertEquals(20, ReflectionUtils.callGetter(serverSocket, "Option", tcpKeepIdle, SocketOption.class, Integer.class)); - - final SocketOption tcpKeepInterval = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPINTERVAL); - assert tcpKeepInterval != null; - Assertions.assertEquals(21, ReflectionUtils.callGetter(serverSocket, "Option", tcpKeepInterval, SocketOption.class, Integer.class)); - - final SocketOption tcpKeepCount = SocketSupport.getExtendedSocketOptionOrNull(SocketSupport.TCP_KEEPCOUNT); - assert tcpKeepCount != null; - Assertions.assertEquals(22, ReflectionUtils.callGetter(serverSocket, "Option", tcpKeepCount, SocketOption.class, Integer.class)); - } - } - } - - public static boolean isWindows() { - return System.getProperty("os.name").contains("Windows"); - } - -} diff --git a/pom.xml b/pom.xml index 5d4584f851..9ea2647b85 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 3.1.10 1.21.3 5.3 - javax.net.ssl.SSLEngine,javax.net.ssl.SSLParameters,java.nio.ByteBuffer,java.nio.CharBuffer + javax.net.ssl.SSLEngine,javax.net.ssl.SSLParameters,java.nio.ByteBuffer,java.nio.CharBuffer,jdk.net.ExtendedSocketOptions,jdk.net.Sockets