diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java index 3132642a57..3939296ffa 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java @@ -30,6 +30,8 @@ public interface QosConstants { String ACCEPT_FOREIGN_IP = "qos.accept.foreign.ip"; + String ACCEPT_FOREIGN_IP_WHITELIST = "qos.accept.foreign.ip.whitelist"; + String QOS_ENABLE_COMPATIBLE = "qos-enable"; String QOS_HOST_COMPATIBLE = "qos-host"; @@ -37,4 +39,6 @@ public interface QosConstants { String QOS_PORT_COMPATIBLE = "qos-port"; String ACCEPT_FOREIGN_IP_COMPATIBLE = "qos-accept-foreign-ip"; + + String ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE = "qos-accept-foreign-ip-whitelist"; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java index c9597d2e7e..33852d430a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java @@ -50,6 +50,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_COMPATIBLE; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST; @@ -149,6 +151,11 @@ public class ApplicationConfig extends AbstractConfig { */ private Boolean qosAcceptForeignIp; + /** + * When we disable accept foreign ip, support specify foreign ip in the whitelist + */ + private String qosAcceptForeignIpWhitelist; + /** * Customized parameters */ @@ -400,6 +407,15 @@ public class ApplicationConfig extends AbstractConfig { this.qosAcceptForeignIp = qosAcceptForeignIp; } + @Parameter(key = ACCEPT_FOREIGN_IP_WHITELIST) + public String getQosAcceptForeignIpWhitelist() { + return qosAcceptForeignIpWhitelist; + } + + public void setQosAcceptForeignIpWhitelist(String qosAcceptForeignIpWhitelist) { + this.qosAcceptForeignIpWhitelist = qosAcceptForeignIpWhitelist; + } + /** * The format is the same as the springboot, including: getQosEnableCompatible(), getQosPortCompatible(), getQosAcceptForeignIpCompatible(). * @@ -441,6 +457,15 @@ public class ApplicationConfig extends AbstractConfig { this.setQosAcceptForeignIp(qosAcceptForeignIp); } + @Parameter(key = ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE, excluded = true, attribute = false) + public String getQosAcceptForeignIpWhitelistCompatible() { + return this.getQosAcceptForeignIpWhitelist(); + } + + public void setQosAcceptForeignIpWhitelistCompatible(String qosAcceptForeignIpWhitelist) { + this.setQosAcceptForeignIpWhitelist(qosAcceptForeignIpWhitelist); + } + public Map getParameters() { return parameters; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java index 668acc408b..db1a87c8dc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java @@ -18,6 +18,7 @@ package org.apache.dubbo.config; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_COMPATIBLE; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT_COMPATIBLE; @@ -140,7 +141,7 @@ public interface Constants { String MULTI_SERIALIZATION_KEY = "serialize.multiple"; String[] DOT_COMPATIBLE_KEYS = new String[]{QOS_ENABLE_COMPATIBLE, QOS_HOST_COMPATIBLE, QOS_PORT_COMPATIBLE, - ACCEPT_FOREIGN_IP_COMPATIBLE, REGISTRY_TYPE_KEY}; + ACCEPT_FOREIGN_IP_COMPATIBLE, ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE, REGISTRY_TYPE_KEY}; String IGNORE_CHECK_KEYS = "ignoreCheckKeys"; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java index 18139f0fad..32b32c4cbf 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.common.QosConstants; import org.apache.dubbo.qos.pu.QosWireProtocol; import org.apache.dubbo.qos.server.Server; @@ -37,6 +38,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_FAILED_START_SERVER; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST; import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT; @@ -113,6 +115,7 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware { String host = url.getParameter(QOS_HOST); int port = url.getParameter(QOS_PORT, QosConstants.DEFAULT_PORT); boolean acceptForeignIp = Boolean.parseBoolean(url.getParameter(ACCEPT_FOREIGN_IP, "false")); + String acceptForeignIpWhitelist = url.getParameter(ACCEPT_FOREIGN_IP_WHITELIST, StringUtils.EMPTY_STRING); Server server = frameworkModel.getBeanFactory().getBean(Server.class); if (server.isStarted()) { @@ -122,6 +125,7 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware { server.setHost(host); server.setPort(port); server.setAcceptForeignIp(acceptForeignIp); + server.setAcceptForeignIpWhitelist(acceptForeignIpWhitelist); server.start(); } catch (Throwable throwable) { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java index 71e6633eb3..9f9a998d19 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java @@ -18,6 +18,7 @@ package org.apache.dubbo.qos.pu; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.server.DubboLogo; import org.apache.dubbo.qos.server.handler.QosProcessHandler; import org.apache.dubbo.remoting.ChannelHandler; @@ -48,7 +49,7 @@ public class QosWireProtocol extends AbstractWireProtocol implements ScopeModelA public void configServerProtocolHandler(URL url, ChannelOperator operator) { // add qosProcess handler QosProcessHandler handler = new QosProcessHandler(url.getOrDefaultFrameworkModel(), - DubboLogo.DUBBO, false); + DubboLogo.DUBBO, false, StringUtils.EMPTY_STRING); List handlers = new ArrayList<>(); handlers.add(new ChannelHandlerPretender(handler)); operator.configChannelHandler(handlers); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java index fa40444e61..2d60b24457 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java @@ -52,6 +52,7 @@ public class Server { private int port; private boolean acceptForeignIp = true; + private String acceptForeignIpWhitelist = StringUtils.EMPTY_STRING; private EventLoopGroup boss; @@ -97,7 +98,7 @@ public class Server { @Override protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(new QosProcessHandler(frameworkModel, welcome, acceptForeignIp)); + ch.pipeline().addLast(new QosProcessHandler(frameworkModel, welcome, acceptForeignIp, acceptForeignIpWhitelist)); } }); try { @@ -147,6 +148,10 @@ public class Server { this.acceptForeignIp = acceptForeignIp; } + public void setAcceptForeignIpWhitelist(String acceptForeignIpWhitelist) { + this.acceptForeignIpWhitelist = acceptForeignIpWhitelist; + } + public String getWelcome() { return welcome; } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java new file mode 100644 index 0000000000..c63072a9de --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java @@ -0,0 +1,94 @@ +/* + * 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. + */ +package org.apache.dubbo.qos.server.handler; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerAdapter; +import io.netty.channel.ChannelHandlerContext; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.qos.common.QosConstants; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.function.Predicate; + +public class ForeignHostPermitHandler extends ChannelHandlerAdapter { + + // true means to accept foreign IP + private boolean acceptForeignIp; + + // the whitelist of foreign IP when acceptForeignIp = false, the delimiter is colon(,) + // support specific ip and an ip range from CIDR specification + private String acceptForeignIpWhitelist; + private Predicate whitelistPredicate = foreignIp -> false; + + public ForeignHostPermitHandler(boolean acceptForeignIp, String foreignIpWhitelist) { + this.acceptForeignIp = acceptForeignIp; + this.acceptForeignIpWhitelist = foreignIpWhitelist; + if (StringUtils.isNotEmpty(foreignIpWhitelist)) { + whitelistPredicate = Arrays.stream(foreignIpWhitelist.split(",")) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .map(foreignIpPattern -> (Predicate) foreignIp -> { + try { + // hard code port to -1 + return NetUtils.matchIpExpression(foreignIpPattern, foreignIp, -1); + } catch (UnknownHostException ignore) { + // ignore illegal CIDR specification + } + return false; + }) + .reduce(Predicate::or).orElse(s -> false); + } + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (acceptForeignIp) { + return; + } + + final InetAddress inetAddress = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress(); + // loopback address, return + if (inetAddress.isLoopbackAddress()) { + return; + } + + // the ip is in the whitelist, return + if (checkForeignIpInWhiteList(inetAddress)) { + return; + } + + ByteBuf cb = Unpooled.wrappedBuffer((QosConstants.BR_STR + "Foreign Ip Not Permitted, Consider Config It In Whitelist." + + QosConstants.BR_STR).getBytes()); + ctx.writeAndFlush(cb).addListener(ChannelFutureListener.CLOSE); + } + + private boolean checkForeignIpInWhiteList(InetAddress inetAddress) { + if (StringUtils.isEmpty(acceptForeignIpWhitelist)) { + return false; + } + + final String foreignIp = inetAddress.getHostAddress(); + return whitelistPredicate.test(foreignIp); + } +} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java deleted file mode 100644 index d93284ae7f..0000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java +++ /dev/null @@ -1,48 +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. - */ -package org.apache.dubbo.qos.server.handler; - -import org.apache.dubbo.qos.common.QosConstants; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerAdapter; -import io.netty.channel.ChannelHandlerContext; - -import java.net.InetSocketAddress; - -public class LocalHostPermitHandler extends ChannelHandlerAdapter { - - // true means to accept foreign IP - private boolean acceptForeignIp; - - public LocalHostPermitHandler(boolean acceptForeignIp) { - this.acceptForeignIp = acceptForeignIp; - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { - if (!acceptForeignIp) { - if (!((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().isLoopbackAddress()) { - ByteBuf cb = Unpooled.wrappedBuffer((QosConstants.BR_STR + "Foreign Ip Not Permitted." - + QosConstants.BR_STR).getBytes()); - ctx.writeAndFlush(cb).addListener(ChannelFutureListener.CLOSE); - } - } - } -} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java index 4e5ef439f8..32d89f7278 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java @@ -44,15 +44,17 @@ public class QosProcessHandler extends ByteToMessageDecoder { private String welcome; // true means to accept foreign IP private boolean acceptForeignIp; + private String acceptForeignIpWhitelist; private FrameworkModel frameworkModel; public static final String PROMPT = "dubbo>"; - public QosProcessHandler(FrameworkModel frameworkModel, String welcome, boolean acceptForeignIp) { + public QosProcessHandler(FrameworkModel frameworkModel, String welcome, boolean acceptForeignIp, String acceptForeignIpWhitelist) { this.frameworkModel = frameworkModel; this.welcome = welcome; this.acceptForeignIp = acceptForeignIp; + this.acceptForeignIpWhitelist = acceptForeignIpWhitelist; } @Override @@ -75,7 +77,7 @@ public class QosProcessHandler extends ByteToMessageDecoder { final int magic = in.getByte(in.readerIndex()); ChannelPipeline p = ctx.pipeline(); - p.addLast(new LocalHostPermitHandler(acceptForeignIp)); + p.addLast(new ForeignHostPermitHandler(acceptForeignIp, acceptForeignIpWhitelist)); if (isHttp(magic)) { // no welcome output for http protocol if (welcomeFuture != null && welcomeFuture.isCancellable()) { diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java new file mode 100644 index 0000000000..0cebdbdc67 --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java @@ -0,0 +1,110 @@ +/* + * 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. + */ +package org.apache.dubbo.qos.server.handler; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import org.apache.dubbo.common.utils.StringUtils; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ForeignHostPermitHandlerTest { + @Test + void shouldShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndEmptyWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + ChannelFuture future = mock(ChannelFuture.class); + when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, StringUtils.EMPTY_STRING); + handler.handlerAdded(context); + ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); + verify(context).writeAndFlush(captor.capture()); + assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted, Consider Config It In Whitelist")); + verify(future).addListener(ChannelFutureListener.CLOSE); + } + + @Test + void shouldShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndNotMatchWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("179.23.44.1"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + ChannelFuture future = mock(ChannelFuture.class); + when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1 , 192.168.1.192/26"); + handler.handlerAdded(context); + ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); + verify(context).writeAndFlush(captor.capture()); + assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted, Consider Config It In Whitelist")); + verify(future).addListener(ChannelFutureListener.CLOSE); + } + + @Test + void shouldNotShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndMatchWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("175.23.44.1"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1, 192.168.1.192/26 "); + handler.handlerAdded(context); + verify(context, never()).writeAndFlush(any()); + } + + @Test + void shouldNotShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndMatchWhiteListRange() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("192.168.1.199"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1, 192.168.1.192/26"); + handler.handlerAdded(context); + verify(context, never()).writeAndFlush(any()); + } +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java deleted file mode 100644 index 9d11d080e8..0000000000 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java +++ /dev/null @@ -1,56 +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. - */ -package org.apache.dubbo.qos.server.handler; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import java.net.InetAddress; -import java.net.InetSocketAddress; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -class LocalHostPermitHandlerTest { - @Test - void testHandlerAdded() throws Exception { - ChannelHandlerContext context = mock(ChannelHandlerContext.class); - Channel channel = mock(Channel.class); - when(context.channel()).thenReturn(channel); - InetAddress addr = mock(InetAddress.class); - when(addr.isLoopbackAddress()).thenReturn(false); - InetSocketAddress address = new InetSocketAddress(addr, 12345); - when(channel.remoteAddress()).thenReturn(address); - ChannelFuture future = mock(ChannelFuture.class); - when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); - LocalHostPermitHandler handler = new LocalHostPermitHandler(false); - handler.handlerAdded(context); - ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); - verify(context).writeAndFlush(captor.capture()); - assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted")); - verify(future).addListener(ChannelFutureListener.CLOSE); - } -} \ No newline at end of file diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java index 0ba4909a01..3649bcdeca 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.qos.server.handler; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.buffer.ByteBuf; @@ -42,7 +43,7 @@ class QosProcessHandlerTest { ChannelHandlerContext context = Mockito.mock(ChannelHandlerContext.class); ChannelPipeline pipeline = Mockito.mock(ChannelPipeline.class); Mockito.when(context.pipeline()).thenReturn(pipeline); - QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false); + QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false, StringUtils.EMPTY_STRING); handler.decode(context, buf, Collections.emptyList()); verify(pipeline).addLast(any(HttpServerCodec.class)); verify(pipeline).addLast(any(HttpObjectAggregator.class)); @@ -56,7 +57,7 @@ class QosProcessHandlerTest { ChannelHandlerContext context = Mockito.mock(ChannelHandlerContext.class); ChannelPipeline pipeline = Mockito.mock(ChannelPipeline.class); Mockito.when(context.pipeline()).thenReturn(pipeline); - QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false); + QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false, StringUtils.EMPTY_STRING); handler.decode(context, buf, Collections.emptyList()); verify(pipeline).addLast(any(LineBasedFrameDecoder.class)); verify(pipeline).addLast(any(StringDecoder.class)); @@ -66,4 +67,4 @@ class QosProcessHandlerTest { } -} \ No newline at end of file +}