From 9ae227a1e164cf7614e50dcde4d7aeab7d38f3bd Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 21 May 2021 12:00:07 +1000 Subject: [PATCH] Fix #6305 Optimise isProtectedTarget updates from review Signed-off-by: Greg Wilkins --- .../jetty/server/handler/ContextHandler.java | 40 ++++++++++--------- .../java/org/eclipse/jetty/util/Index.java | 3 +- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 168b87c47939..b011b5a445a4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -180,6 +180,16 @@ public enum ContextStatus DESTROYED } + /** + * The type of protected target match + * @see #_protectedTargets + */ + private enum ProtectedTargetType + { + EXACT, + PREFIX + } + protected ContextStatus _contextStatus = ContextStatus.NOTSET; protected Context _scontext; private final AttributesMap _attributes; @@ -215,7 +225,7 @@ public enum ContextStatus private final List _servletRequestAttributeListeners = new CopyOnWriteArrayList<>(); private final List _contextListeners = new CopyOnWriteArrayList<>(); private final Set _durableListeners = new HashSet<>(); - private Index _protectedTargets = Index.empty(false); + private Index _protectedTargets = Index.empty(false); private final CopyOnWriteArrayList _aliasChecks = new CopyOnWriteArrayList<>(); public enum Availability @@ -1482,16 +1492,10 @@ public boolean isProtectedTarget(String target) // ignore empty segments which may be discard by file system target = URIUtil.compactPath(target); - Boolean exact = _protectedTargets.getBest(target); + ProtectedTargetType type = _protectedTargets.getBest(target); - if (exact == null) - // Not protected - return false; - if (exact) - // protected if exact length - return _protectedTargets.get(target) == Boolean.TRUE; - // protected prefix - return true; + return type == ProtectedTargetType.PREFIX || + type == ProtectedTargetType.EXACT && _protectedTargets.get(target) == ProtectedTargetType.EXACT; } /** @@ -1499,19 +1503,19 @@ public boolean isProtectedTarget(String target) */ public void setProtectedTargets(String[] targets) { - Index.Builder builder = new Index.Builder<>(); + Index.Builder builder = new Index.Builder<>(); if (targets != null) { for (String t : targets) { - if (!t.startsWith("/") || t.indexOf('/', 2) > 0) + if (!t.startsWith("/")) throw new IllegalArgumentException("Bad protected target: " + t); - // Index to TRUE if exact match required - builder.with(t, Boolean.TRUE); - // Index to FALSE for prefix matches - for (String s : new String[] {"/", "?", "#", ";"}) - builder.with(t + s, Boolean.FALSE); + builder.with(t, ProtectedTargetType.EXACT); + builder.with(t + "/", ProtectedTargetType.PREFIX); + builder.with(t + "?", ProtectedTargetType.PREFIX); + builder.with(t + "#", ProtectedTargetType.PREFIX); + builder.with(t + ";", ProtectedTargetType.PREFIX); } } _protectedTargets = builder.caseSensitive(false).build(); @@ -1523,7 +1527,7 @@ public String[] getProtectedTargets() return null; return _protectedTargets.keySet().stream() - .filter(_protectedTargets::get) + .filter(s -> _protectedTargets.get(s) == ProtectedTargetType.EXACT) .toArray(String[]::new); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Index.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Index.java index 41279fb9bb18..1b79b0fa21c5 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Index.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Index.java @@ -73,7 +73,8 @@ public interface Index V getBest(String s, int offset, int len); /** - * Get the best match from key in a String. + * Get the best match from key in a String, which may be + * a prefix match or an exact match. * * @param s The string * @return The value or null if not found