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 288ebb4e5..1dacdd236 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 @@ -86,9 +86,9 @@ import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPCOUNT; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPIDLE; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPINTERVAL; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL; /** * HTTP/1.1 client side message exchange initiator. 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 0c1ba832b..8363c70c2 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 @@ -61,9 +61,9 @@ import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPCOUNT; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPIDLE; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPINTERVAL; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL; /** * HTTP/1.1 server side message exchange handler. 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 ba0f222af..2b50caa11 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,9 +47,9 @@ import org.apache.hc.core5.io.Closer; import org.apache.hc.core5.util.ReflectionUtils; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPCOUNT; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPIDLE; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPINTERVAL; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL; class RequestListener implements Runnable { diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/SocketConfig.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/SocketConfig.java index bfbb0ba57..ee3824c29 100644 --- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/SocketConfig.java +++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/SocketConfig.java @@ -152,16 +152,16 @@ public int getBacklogSize() { * @see Builder#setTcpKeepIdle(int) * @since 5.3 */ - public int getTcpKeepInterval() { - return this.tcpKeepInterval; + public int getTcpKeepIdle() { + return this.tcpKeepIdle; } /** * @see Builder#setTcpKeepInterval(int) * @since 5.3 */ - public int getTcpKeepIdle() { - return this.tcpKeepIdle; + public int getTcpKeepInterval() { + return this.tcpKeepInterval; } /** 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 a3d43b60f..598f27078 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 @@ -43,7 +43,6 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.function.Callback; import org.apache.hc.core5.function.Decorator; @@ -53,14 +52,13 @@ import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.Timeout; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL; import static org.apache.hc.core5.util.ReflectionUtils.getExtendedSocketOptionOrNull; -@Internal -public class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements ConnectionInitiator { +class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements ConnectionInitiator { - public static final String TCP_KEEPIDLE = "TCP_KEEPIDLE"; - public static final String TCP_KEEPINTERVAL = "TCP_KEEPINTERVAL"; - public static final String TCP_KEEPCOUNT = "TCP_KEEPCOUNT"; private static final int MAX_CHANNEL_REQUESTS = 10000; private final IOEventHandlerFactory eventHandlerFactory; diff --git a/httpcore5/src/main/java/org/apache/hc/core5/util/NetUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/util/NetUtils.java new file mode 100644 index 000000000..4016594b1 --- /dev/null +++ b/httpcore5/src/main/java/org/apache/hc/core5/util/NetUtils.java @@ -0,0 +1,12 @@ +package org.apache.hc.core5.util; + +import org.apache.hc.core5.annotation.Internal; + +@Internal +public class NetUtils { + + public static final String TCP_KEEPIDLE = "TCP_KEEPIDLE"; + public static final String TCP_KEEPINTERVAL = "TCP_KEEPINTERVAL"; + public static final String TCP_KEEPCOUNT = "TCP_KEEPCOUNT"; + +} 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 232a42dd5..08f741b8c 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,6 +27,7 @@ package org.apache.hc.core5.util; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.SocketOption; @@ -46,13 +47,25 @@ public static void callSetter(final Object object, final String setterName, fina } } + public static T callGetter(final Object object, final String getterName, final Class resultType) { + return callGetter(object, getterName, null, null, resultType); + } + public static T callGetter(final Object object, final String getterName, final Object arg, final Class argType, final Class resultType) { try { final Class clazz = object.getClass(); final Method method; - method = clazz.getMethod("get" + getterName, argType); - method.setAccessible(true); - return resultType.cast(method.invoke(object, arg)); + if (arg != null) { + assert argType != null; + method = clazz.getMethod("get" + getterName, argType); + method.setAccessible(true); + return resultType.cast(method.invoke(object, arg)); + } else { + assert argType == null; + method = clazz.getMethod("get" + getterName); + method.setAccessible(true); + return resultType.cast(method.invoke(object)); + } } catch (final Exception ignore) { return null; } @@ -78,6 +91,7 @@ public static int determineJRELevel() { /** * @since 5.3 */ + @SuppressWarnings("unchecked") public static SocketOption getExtendedSocketOptionOrNull(final String fieldName) { try { final Class extendedSocketOptionsClass = Class.forName("jdk.net.ExtendedSocketOptions"); @@ -93,17 +107,20 @@ public static SocketOption getExtendedSocketOptionOrNull(final String fie * * @since 5.3 */ - public static void setOption(final T object, final String fieldName, final T value) { + 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 tcpKeepIdle = getExtendedSocketOptionOrNull(fieldName); - if (tcpKeepIdle == null) { + final SocketOption socketOption = getExtendedSocketOptionOrNull(fieldName); + if (socketOption == null) { throw new UnsupportedOperationException(fieldName + " is not supported in the current jdk"); } - setOptionMethod.invoke(object, tcpKeepIdle, value); - } catch (final Exception ignore) { - throw new UnsupportedOperationException(fieldName + " is not supported in the current jdk"); + setOptionMethod.invoke(object, socketOption, value); + } catch (final UnsupportedOperationException e) { + throw e; + } catch (final Exception e) { + throw new IOException("failed to call setOption", e); } } + } diff --git a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestSingleCoreIOReactor.java b/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestSingleCoreIOReactor.java deleted file mode 100644 index fb5894e96..000000000 --- a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestSingleCoreIOReactor.java +++ /dev/null @@ -1,68 +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.reactor; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.SocketOption; -import java.nio.channels.SocketChannel; - -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPCOUNT; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPIDLE; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPINTERVAL; -import static org.apache.hc.core5.util.ReflectionUtils.determineJRELevel; -import static org.apache.hc.core5.util.ReflectionUtils.getExtendedSocketOptionOrNull; -import static org.apache.hc.core5.util.TestReflectionUtils.isWindows; -import static org.mockito.Mockito.mock; - -public class TestSingleCoreIOReactor { - @Test - public void testSetExtendedSocketOption() throws IOException { - final SingleCoreIOReactor reactor = new SingleCoreIOReactor(null, mock(IOEventHandlerFactory.class), IOReactorConfig.DEFAULT, null, null, null); - final SocketChannel socketChannel = SocketChannel.open(); - final SocketOption tcpKeepIdle; - final SocketOption tcpKeepInterval; - final SocketOption tcpKeepCount; - // 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 (determineJRELevel() > 8 && isWindows() == false) { - reactor.setExtendedSocketOption(socketChannel, TCP_KEEPIDLE, 100); - reactor.setExtendedSocketOption(socketChannel, TCP_KEEPINTERVAL, 10); - reactor.setExtendedSocketOption(socketChannel, TCP_KEEPCOUNT, 10); - - tcpKeepIdle = getExtendedSocketOptionOrNull(TCP_KEEPIDLE); - tcpKeepInterval = getExtendedSocketOptionOrNull(TCP_KEEPINTERVAL); - tcpKeepCount = getExtendedSocketOptionOrNull(TCP_KEEPCOUNT); - Assertions.assertEquals(100, socketChannel.getOption(tcpKeepIdle)); - Assertions.assertEquals(10, socketChannel.getOption(tcpKeepInterval)); - Assertions.assertEquals(10, socketChannel.getOption(tcpKeepCount)); - } - } -} diff --git a/httpcore5/src/test/java/org/apache/hc/core5/util/TestReflectionUtils.java b/httpcore5/src/test/java/org/apache/hc/core5/util/TestReflectionUtils.java index c735a2b36..b29c448a9 100644 --- a/httpcore5/src/test/java/org/apache/hc/core5/util/TestReflectionUtils.java +++ b/httpcore5/src/test/java/org/apache/hc/core5/util/TestReflectionUtils.java @@ -36,9 +36,9 @@ import java.net.Socket; import java.net.SocketOption; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPCOUNT; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPIDLE; -import static org.apache.hc.core5.reactor.SingleCoreIOReactor.TCP_KEEPINTERVAL; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPCOUNT; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPIDLE; +import static org.apache.hc.core5.util.NetUtils.TCP_KEEPINTERVAL; import static org.apache.hc.core5.util.ReflectionUtils.callGetter; import static org.apache.hc.core5.util.ReflectionUtils.determineJRELevel; import static org.apache.hc.core5.util.ReflectionUtils.setOption; @@ -53,8 +53,8 @@ public void testGetExtendedSocketOptionOrNull() { testGetExtendedSocketOption(TCP_KEEPCOUNT); } - private void testGetExtendedSocketOption(final String option) { - final SocketOption socketOption = getExtendedSocketOptionOrNull(option); + private void testGetExtendedSocketOption(final String option) { + final SocketOption socketOption = 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 (determineJRELevel() > 8 && isWindows() == false) { @@ -110,4 +110,5 @@ public void testSetOption() throws IOException { public static boolean isWindows() { return System.getProperty("os.name").contains("Windows"); } + }