一、RuleBasedIpFilter
RuleBasedIpFilter是基于ip的过滤器,可以自定义哪些ip或者ip范围允许通过或者被阻止。因为默认情况下,如果不添加任何IpSubnetFilterRule, RuleBasedIpFilter就会允许所有ip。如果我们使用白名单机制,要么继承RuleBasedIpFilter类,重写accept方法,要不在RuleBasedIpFilter, 添加一个rejectAll,并将该rejectAll放在数组的最后。
1.1 源码-netty自带
@Sharable
public class RuleBasedIpFilter extends AbstractRemoteAddressFilter<InetSocketAddress> {
private final IpFilterRule[] rules;
public RuleBasedIpFilter(IpFilterRule... rules) {
if (rules == null) {
throw new NullPointerException("rules");
}
this.rules = rules;
}
@Override
protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) throws Exception {
for (IpFilterRule rule : rules) {
if (rule == null) {
break;
}
if (rule.matches(remoteAddress)) {
return rule.ruleType() == IpFilterRuleType.ACCEPT;
}
}
return true;
}
}
RuleBasedIpFilter类图:
可以看到它实际上是一个ChannelHandler,所以是一定要加入到pipeline中的。
1.2 分析RuleBasedIpFilter如何实现
上面说了RuleBasedIpFilter是AbstractRemoteAddressFilter的子类,而AbstractRemoteAddressFilter是ChannelInboundHandlerAdapter的子类。它重载了channelRegistered、channelActive等方法。上面这段文字是我们下面分析的基础
先贴流程:
- channelRegistered()——>handleNewChannel()——>accept()——>IpFilterRule.matches();
- channelActive()——>handleNewChannel()——>accept()——>IpFilterRule.matches();
上述两个调用链, 结合下面源码就能明白RuleBasedIpFilter是如何实现ip过滤的了。
1. channelRegistered()和channelActive()会调用handleNewChannel()
2.handleNewChannel()代码中调用accept()方法,accept方法就是RuleBasedIpFilter类中方法。
3.accept方法中调用了
4.所以需要我们做的就是,写一个类继承IpFilterRule,重写matches方法和ruleType方法
二、代码实现
1.在pipeline中加入RuleBasedIpFilter对象,并在对象中传入我们自定写的IpFilterRuleHandler对象,它继承了IpFilterRule。
2. 重写IpFilterRuleHandler的matches方法和ruleType方法