implements Predicate
public void include(T... element)
{
- for (T e : element)
- {
- _includes.add(e);
- }
+ _includes.addAll(Arrays.asList(element));
}
public void exclude(T element)
@@ -158,10 +156,7 @@ public class IncludeExcludeSet implements Predicate
public void exclude(T... element)
{
- for (T e : element)
- {
- _excludes.add(e);
- }
+ _excludes.addAll(Arrays.asList(element));
}
@Override
@@ -233,34 +228,4 @@ public class IncludeExcludeSet implements Predicate
{
return _includes.isEmpty() && _excludes.isEmpty();
}
-
- /**
- * Match items in combined IncludeExcludeSets.
- * @param item1 The item to match against set1
- * @param set1 A IncludeExcludeSet to match item1 against
- * @param item2 The item to match against set2
- * @param set2 A IncludeExcludeSet to match item2 against
- * @param The type of item1
- * @param The type of item2
- * @return True IFF
- * - Neither item is excluded from their respective sets
- * - Both sets have no includes OR at least one of the items is included in its respective set
- *
- */
- public static boolean matchCombined(T1 item1, IncludeExcludeSet,T1> set1, T2 item2, IncludeExcludeSet,T2> set2)
- {
- Boolean match1 = set1.isIncludedAndNotExcluded(item1);
- Boolean match2 = set2.isIncludedAndNotExcluded(item2);
-
- // if we are excluded from either set, then we do not match
- if (match1 == Boolean.FALSE || match2 == Boolean.FALSE)
- return false;
-
- // If either set has any includes, then we must be included by one of them
- if (set1.hasIncludes() || set2.hasIncludes())
- return match1 == Boolean.TRUE || match2 == Boolean.TRUE;
-
- // If not excluded and no includes, then we match
- return true;
- }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressPattern.java b/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressPattern.java
new file mode 100644
index 00000000000..e64b818de5a
--- /dev/null
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressPattern.java
@@ -0,0 +1,282 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under
+// the terms of the Eclipse Public License 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0
+//
+// This Source Code may also be made available under the following
+// Secondary Licenses when the conditions for such availability set
+// forth in the Eclipse Public License, v. 2.0 are satisfied:
+// the Apache License v2.0 which is available at
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.util;
+
+import java.net.InetAddress;
+import java.util.function.Predicate;
+
+/**
+ * A pattern representing a single or range of {@link InetAddress}. To create a pattern use
+ * the {@link InetAddressPattern#from(String)} method, which will create a pattern given a
+ * string conforming to one of the following formats.
+ *
+ *
+ * - InetAddress
+ * - A single InetAddress either in hostname or address format.
+ * All formats supported by {@link InetAddress} are accepted. Not ethat using hostname
+ * matches may force domain lookups. eg. "[::1]", "1.2.3.4", "::ffff:127.0.0.1"
+ * - InetAddress/CIDR
+ * - An InetAddress with a integer number of bits to indicate
+ * the significant prefix. eg. "192.168.0.0/16" will match from "192.168.0.0" to
+ * "192.168.255.255"
+ * - InetAddress-InetAddress
+ * - An inclusive range of InetAddresses.
+ * eg. "[a000::1]-[afff::]", "192.168.128.0-192.168.128.255"
+ * - Legacy format
+ * - The legacy format used for IPv4 only.
+ * eg. "10.10.10-14.0-128"
+ *
+ */
+public abstract class InetAddressPattern implements Predicate
+{
+ protected final String _pattern;
+
+ public static InetAddressPattern from(String pattern)
+ {
+ if (pattern == null)
+ return null;
+
+ int slash = pattern.lastIndexOf('/');
+ int dash = pattern.lastIndexOf('-');
+ try
+ {
+ if (slash >= 0)
+ return new CidrInetAddressRange(pattern, InetAddress.getByName(pattern.substring(0, slash).trim()), StringUtil.toInt(pattern, slash + 1));
+
+ if (dash >= 0)
+ return new MinMaxInetAddressRange(pattern, InetAddress.getByName(pattern.substring(0, dash).trim()), InetAddress.getByName(pattern.substring(dash + 1).trim()));
+
+ return new SingletonInetAddressRange(pattern, InetAddress.getByName(pattern));
+ }
+ catch (Exception e)
+ {
+ try
+ {
+ if (slash < 0 && dash > 0)
+ return new LegacyInetAddressRange(pattern);
+ }
+ catch (Exception ex2)
+ {
+ e.addSuppressed(ex2);
+ }
+ throw new IllegalArgumentException("Bad pattern: " + pattern, e);
+ }
+ }
+
+ public InetAddressPattern(String pattern)
+ {
+ _pattern = pattern;
+ }
+
+ @Override
+ public String toString()
+ {
+ return _pattern;
+ }
+
+ static class SingletonInetAddressRange extends InetAddressPattern
+ {
+ final InetAddress _address;
+
+ public SingletonInetAddressRange(String pattern, InetAddress address)
+ {
+ super(pattern);
+ _address = address;
+ }
+
+ @Override
+ public boolean test(InetAddress address)
+ {
+ return _address.equals(address);
+ }
+ }
+
+ static class MinMaxInetAddressRange extends InetAddressPattern
+ {
+ final int[] _min;
+ final int[] _max;
+
+ public MinMaxInetAddressRange(String pattern, InetAddress min, InetAddress max)
+ {
+ super(pattern);
+
+ byte[] rawMin = min.getAddress();
+ byte[] rawMax = max.getAddress();
+ if (rawMin.length != rawMax.length)
+ throw new IllegalArgumentException("Cannot mix IPv4 and IPv6: " + pattern);
+
+ if (rawMin.length == 4)
+ {
+ // there must be 6 '.' or this is likely to be a legacy pattern
+ int count = 0;
+ for (char c : pattern.toCharArray())
+ {
+ if (c == '.')
+ count++;
+ }
+ if (count != 6)
+ throw new IllegalArgumentException("Legacy pattern: " + pattern);
+ }
+
+ _min = new int[rawMin.length];
+ _max = new int[rawMin.length];
+
+ for (int i = 0; i < _min.length; i++)
+ {
+ _min[i] = 0xff & rawMin[i];
+ _max[i] = 0xff & rawMax[i];
+ }
+
+ for (int i = 0; i < _min.length; i++)
+ {
+ if (_min[i] > _max[i])
+ throw new IllegalArgumentException("min is greater than max: " + pattern);
+ if (_min[i] < _max[i])
+ break;
+ }
+ }
+
+ @Override
+ public boolean test(InetAddress address)
+ {
+ byte[] raw = address.getAddress();
+ if (raw.length != _min.length)
+ return false;
+
+ boolean minOk = false;
+ boolean maxOk = false;
+
+ for (int i = 0; i < _min.length; i++)
+ {
+ int r = 0xff & raw[i];
+ if (!minOk)
+ {
+ if (r < _min[i])
+ return false;
+ if (r > _min[i])
+ minOk = true;
+ }
+ if (!maxOk)
+ {
+ if (r > _max[i])
+ return false;
+ if (r < _max[i])
+ maxOk = true;
+ }
+
+ if (minOk && maxOk)
+ break;
+ }
+
+ return true;
+ }
+ }
+
+ static class CidrInetAddressRange extends InetAddressPattern
+ {
+ final byte[] _raw;
+ final int _octets;
+ final int _mask;
+ final int _masked;
+
+ public CidrInetAddressRange(String pattern, InetAddress address, int cidr)
+ {
+ super(pattern);
+ _raw = address.getAddress();
+ _octets = cidr / 8;
+ _mask = 0xff & (0xff << (8 - cidr % 8));
+ _masked = _mask == 0 ? 0 : _raw[_octets] & _mask;
+
+ if (cidr > (_raw.length * 8))
+ throw new IllegalArgumentException("CIDR too large: " + pattern);
+
+ if (_mask != 0 && (0xff & _raw[_octets]) != _masked)
+ throw new IllegalArgumentException("CIDR bits non zero: " + pattern);
+
+ for (int o = _octets + (_mask == 0 ? 0 : 1); o < _raw.length; o++)
+ {
+ if (_raw[o] != 0)
+ throw new IllegalArgumentException("CIDR bits non zero: " + pattern);
+ }
+ }
+
+ @Override
+ public boolean test(InetAddress address)
+ {
+ byte[] raw = address.getAddress();
+ if (raw.length != _raw.length)
+ return false;
+
+ for (int o = 0; o < _octets; o++)
+ {
+ if (_raw[o] != raw[o])
+ return false;
+ }
+
+ return _mask == 0 || (raw[_octets] & _mask) == _masked;
+ }
+ }
+
+ static class LegacyInetAddressRange extends InetAddressPattern
+ {
+ int[] _min = new int[4];
+ int[] _max = new int[4];
+
+ public LegacyInetAddressRange(String pattern)
+ {
+ super(pattern);
+
+ String[] parts = pattern.split("\\.");
+ if (parts.length != 4)
+ throw new IllegalArgumentException("Bad legacy pattern: " + pattern);
+
+ for (int i = 0; i < 4; i++)
+ {
+ String part = parts[i].trim();
+ int dash = part.indexOf('-');
+ if (dash < 0)
+ _min[i] = _max[i] = Integer.parseInt(part);
+ else
+ {
+ _min[i] = (dash == 0) ? 0 : StringUtil.toInt(part, 0);
+ _max[i] = (dash == part.length() - 1) ? 255 : StringUtil.toInt(part, dash + 1);
+ }
+
+ if (_min[i] < 0 || _min[i] > _max[i] || _max[i] > 255)
+ throw new IllegalArgumentException("Bad legacy pattern: " + pattern);
+ }
+ }
+
+ @Override
+ public boolean test(InetAddress address)
+ {
+ byte[] raw = address.getAddress();
+ if (raw.length != 4)
+ return false;
+
+ for (int i = 0; i < 4; i++)
+ {
+ if ((0xff & raw[i]) < _min[i] || (0xff & raw[i]) > _max[i])
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressSet.java b/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressSet.java
index 621cdb7905c..6aa3e9038f9 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressSet.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressSet.java
@@ -30,62 +30,20 @@ import java.util.function.Predicate;
* A set of InetAddress patterns.
* This is a {@link Set} of String patterns that are used to match
* a {@link Predicate} over InetAddress for containment semantics.
- * The patterns that may be set are:
+ * The patterns that may be set are defined in {@link InetAddressPattern}.
*
- *
- * - InetAddress
- A single InetAddress either in hostname or address format.
- * All formats supported by {@link InetAddress} are accepted. Not ethat using hostname
- * matches may force domain lookups. eg. "[::1]", "1.2.3.4", "::ffff:127.0.0.1"
- * - InetAddress/CIDR
- An InetAddress with a integer number of bits to indicate
- * the significant prefix. eg. "192.168.0.0/16" will match from "192.168.0.0" to
- * "192.168.255.255"
- * - InetAddress-InetAddress
- An inclusive range of InetAddresses.
- * eg. "[a000::1]-[afff::]", "192.168.128.0-192.168.128.255"
- *
* This class is designed to work with {@link IncludeExcludeSet}
*
* @see IncludeExcludeSet
*/
public class InetAddressSet extends AbstractSet implements Set, Predicate
{
- private Map _patterns = new HashMap<>();
+ private Map _patterns = new HashMap<>();
@Override
public boolean add(String pattern)
{
- return _patterns.put(pattern, newInetRange(pattern)) == null;
- }
-
- private InetPattern newInetRange(String pattern)
- {
- if (pattern == null)
- return null;
-
- int slash = pattern.lastIndexOf('/');
- int dash = pattern.lastIndexOf('-');
- try
- {
- if (slash >= 0)
- return new CidrInetRange(pattern, InetAddress.getByName(pattern.substring(0, slash).trim()), StringUtil.toInt(pattern, slash + 1));
-
- if (dash >= 0)
- return new MinMaxInetRange(pattern, InetAddress.getByName(pattern.substring(0, dash).trim()), InetAddress.getByName(pattern.substring(dash + 1).trim()));
-
- return new SingletonInetRange(pattern, InetAddress.getByName(pattern));
- }
- catch (Exception e)
- {
- try
- {
- if (slash < 0 && dash > 0)
- return new LegacyInetRange(pattern);
- }
- catch (Exception e2)
- {
- e.addSuppressed(e2);
- }
- throw new IllegalArgumentException("Bad pattern: " + pattern, e);
- }
+ return _patterns.put(pattern, InetAddressPattern.from(pattern)) == null;
}
@Override
@@ -111,219 +69,11 @@ public class InetAddressSet extends AbstractSet implements Set,
{
if (address == null)
return false;
- byte[] raw = address.getAddress();
- for (InetPattern pattern : _patterns.values())
+ for (InetAddressPattern pattern : _patterns.values())
{
- if (pattern.test(address, raw))
+ if (pattern.test(address))
return true;
}
return false;
}
-
- abstract static class InetPattern
- {
- final String _pattern;
-
- InetPattern(String pattern)
- {
- _pattern = pattern;
- }
-
- abstract boolean test(InetAddress address, byte[] raw);
-
- @Override
- public String toString()
- {
- return _pattern;
- }
- }
-
- static class SingletonInetRange extends InetPattern
- {
- final InetAddress _address;
-
- public SingletonInetRange(String pattern, InetAddress address)
- {
- super(pattern);
- _address = address;
- }
-
- @Override
- public boolean test(InetAddress address, byte[] raw)
- {
- return _address.equals(address);
- }
- }
-
- static class MinMaxInetRange extends InetPattern
- {
- final int[] _min;
- final int[] _max;
-
- public MinMaxInetRange(String pattern, InetAddress min, InetAddress max)
- {
- super(pattern);
-
- byte[] rawMin = min.getAddress();
- byte[] rawMax = max.getAddress();
- if (rawMin.length != rawMax.length)
- throw new IllegalArgumentException("Cannot mix IPv4 and IPv6: " + pattern);
-
- if (rawMin.length == 4)
- {
- // there must be 6 '.' or this is likely to be a legacy pattern
- int count = 0;
- for (char c : pattern.toCharArray())
- {
- if (c == '.')
- count++;
- }
- if (count != 6)
- throw new IllegalArgumentException("Legacy pattern: " + pattern);
- }
-
- _min = new int[rawMin.length];
- _max = new int[rawMin.length];
-
- for (int i = 0; i < _min.length; i++)
- {
- _min[i] = 0xff & rawMin[i];
- _max[i] = 0xff & rawMax[i];
- }
-
- for (int i = 0; i < _min.length; i++)
- {
- if (_min[i] > _max[i])
- throw new IllegalArgumentException("min is greater than max: " + pattern);
- if (_min[i] < _max[i])
- break;
- }
- }
-
- @Override
- public boolean test(InetAddress item, byte[] raw)
- {
- if (raw.length != _min.length)
- return false;
-
- boolean minOk = false;
- boolean maxOk = false;
-
- for (int i = 0; i < _min.length; i++)
- {
- int r = 0xff & raw[i];
- if (!minOk)
- {
- if (r < _min[i])
- return false;
- if (r > _min[i])
- minOk = true;
- }
- if (!maxOk)
- {
- if (r > _max[i])
- return false;
- if (r < _max[i])
- maxOk = true;
- }
-
- if (minOk && maxOk)
- break;
- }
-
- return true;
- }
- }
-
- static class CidrInetRange extends InetPattern
- {
- final byte[] _raw;
- final int _octets;
- final int _mask;
- final int _masked;
-
- public CidrInetRange(String pattern, InetAddress address, int cidr)
- {
- super(pattern);
- _raw = address.getAddress();
- _octets = cidr / 8;
- _mask = 0xff & (0xff << (8 - cidr % 8));
- _masked = _mask == 0 ? 0 : _raw[_octets] & _mask;
-
- if (cidr > (_raw.length * 8))
- throw new IllegalArgumentException("CIDR too large: " + pattern);
-
- if (_mask != 0 && (0xff & _raw[_octets]) != _masked)
- throw new IllegalArgumentException("CIDR bits non zero: " + pattern);
-
- for (int o = _octets + (_mask == 0 ? 0 : 1); o < _raw.length; o++)
- {
- if (_raw[o] != 0)
- throw new IllegalArgumentException("CIDR bits non zero: " + pattern);
- }
- }
-
- @Override
- public boolean test(InetAddress item, byte[] raw)
- {
- if (raw.length != _raw.length)
- return false;
-
- for (int o = 0; o < _octets; o++)
- {
- if (_raw[o] != raw[o])
- return false;
- }
-
- if (_mask != 0 && (raw[_octets] & _mask) != _masked)
- return false;
- return true;
- }
- }
-
- static class LegacyInetRange extends InetPattern
- {
- int[] _min = new int[4];
- int[] _max = new int[4];
-
- public LegacyInetRange(String pattern)
- {
- super(pattern);
-
- String[] parts = pattern.split("\\.");
- if (parts.length != 4)
- throw new IllegalArgumentException("Bad legacy pattern: " + pattern);
-
- for (int i = 0; i < 4; i++)
- {
- String part = parts[i].trim();
- int dash = part.indexOf('-');
- if (dash < 0)
- _min[i] = _max[i] = Integer.parseInt(part);
- else
- {
- _min[i] = (dash == 0) ? 0 : StringUtil.toInt(part, 0);
- _max[i] = (dash == part.length() - 1) ? 255 : StringUtil.toInt(part, dash + 1);
- }
-
- if (_min[i] < 0 || _min[i] > _max[i] || _max[i] > 255)
- throw new IllegalArgumentException("Bad legacy pattern: " + pattern);
- }
- }
-
- @Override
- public boolean test(InetAddress item, byte[] raw)
- {
- if (raw.length != 4)
- return false;
-
- for (int i = 0; i < 4; i++)
- {
- if ((0xff & raw[i]) < _min[i] || (0xff & raw[i]) > _max[i])
- return false;
- }
-
- return true;
- }
- }
}