diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java index e0d975ca7df..348a4b4284d 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java @@ -44,6 +44,7 @@ public class PathMappings implements Iterable>, Dumpable private static final Logger LOG = Log.getLogger(PathMappings.class); private List> mappings = new ArrayList>(); private MappedResource defaultResource = null; + private MappedResource rootResource = null; @Override public String dump() @@ -105,6 +106,11 @@ public class PathMappings implements Iterable>, Dumpable public MappedResource getMatch(String path) { + if (path.equals("/") && rootResource != null) + { + return rootResource; + } + int len = mappings.size(); for (int i = 0; i < len; i++) { @@ -123,14 +129,22 @@ public class PathMappings implements Iterable>, Dumpable return mappings.iterator(); } + @SuppressWarnings("incomplete-switch") public void put(PathSpec pathSpec, E resource) { MappedResource entry = new MappedResource<>(pathSpec,resource); - if (pathSpec.group == PathSpecGroup.DEFAULT) + switch (pathSpec.group) { - defaultResource = entry; + case DEFAULT: + defaultResource = entry; + break; + case ROOT: + rootResource = entry; + break; } - // TODO: warning on replacement of existing mapping? + + // TODO: add warning when replacing an existing pathspec? + mappings.add(entry); if (LOG.isDebugEnabled()) LOG.debug("Added {} to {}",entry,this); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java index 122211a5586..b9878472bbb 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java @@ -119,7 +119,7 @@ public abstract class PathSpec implements Comparable * * @return the as-provided path spec */ - public String getPathSpec() + public String getDeclaration() { return pathSpec; } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java index 55399748e29..44f8a5fae28 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java @@ -245,7 +245,7 @@ public class ServletPathSpec extends PathSpec case EXACT: return pathSpec.equals(path); case PREFIX_GLOB: - return (!"/".equals(path) && isWildcardMatch(path)); + return isWildcardMatch(path); case SUFFIX_GLOB: return path.regionMatches((path.length() - specLength) + 1,pathSpec,1,specLength - 1); case ROOT: diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java index 06cd14bcce6..36df42e553d 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java @@ -77,61 +77,22 @@ public class PathMappingsTest assertMatch(p,"/animal/fish/trout/cam","animalCam"); assertMatch(p,"/entrance/cam","entranceCam"); } - + /** - * Test the match order rules imposed by the Servlet API. - *

- *

    - *
  • Exact match
  • - *
  • Longest prefix match
  • - *
  • Longest suffix match
  • - *
  • default
  • - *
+ * Test the match order rules imposed by the Servlet API (default vs any) */ @Test - public void testServletMatchOrder() + public void testServletMatchDefault() { PathMappings p = new PathMappings<>(); - p.put(new ServletPathSpec("/abs/path"),"abspath"); // 1 - p.put(new ServletPathSpec("/abs/path/longer"),"longpath"); // 2 - p.put(new ServletPathSpec("/animal/bird/*"),"birds"); // 3 - p.put(new ServletPathSpec("/animal/fish/*"),"fishes"); // 4 - p.put(new ServletPathSpec("/animal/*"),"animals"); // 5 - p.put(new ServletPathSpec("*.tar.gz"),"tarball"); // 6 - p.put(new ServletPathSpec("*.gz"),"gzipped"); // 7 - p.put(new ServletPathSpec("/"),"default"); // 8 - // 9 was the old Jetty ":" spec delimited case (no longer valid) - p.put(new ServletPathSpec(""),"root"); // 10 - p.put(new ServletPathSpec("/\u20ACuro/*"),"money"); // 11 + p.put(new ServletPathSpec("/"),"default"); + p.put(new ServletPathSpec("/*"),"any"); - // dumpMappings(p); - - // From old PathMapTest - assertMatch(p,"/abs/path","abspath"); - assertMatch(p,"/abs/path/xxx","default"); - assertMatch(p,"/abs/pith","default"); - assertMatch(p,"/abs/path/longer","longpath"); - assertMatch(p,"/abs/path/","default"); - assertMatch(p,"/abs/path/foo","default"); - assertMatch(p,"/animal/bird/eagle/bald","birds"); - assertMatch(p,"/animal/fish/shark/hammerhead","fishes"); - assertMatch(p,"/animal/insect/ladybug","animals"); - assertMatch(p,"/animal","animals"); - assertMatch(p,"/animal/","animals"); - assertMatch(p,"/animal/other","animals"); - assertMatch(p,"/animal/*","animals"); - assertMatch(p,"/downloads/distribution.tar.gz","tarball"); - assertMatch(p,"/downloads/script.gz","gzipped"); - assertMatch(p,"/animal/arhive.gz","animals"); - assertMatch(p,"/Other/path","default"); - assertMatch(p,"/\u20ACuro/path","money"); - assertMatch(p,"/","root"); - - // Extra tests - assertMatch(p,"/downloads/readme.txt","default"); - assertMatch(p,"/downloads/logs.tgz","default"); - assertMatch(p,"/main.css","default"); + assertMatch(p,"/abs/path","any"); + assertMatch(p,"/abs/path/xxx","any"); + assertMatch(p,"/animal/bird/eagle/bald","any"); + assertMatch(p,"/","any"); } /** diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java index a44c4dca504..f78cd750409 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java @@ -28,13 +28,13 @@ public class RegexPathSpecTest { public static void assertMatches(PathSpec spec, String path) { - String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(true)); } public static void assertNotMatches(PathSpec spec, String path) { - String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(false)); } @@ -42,7 +42,7 @@ public class RegexPathSpecTest public void testExactSpec() { RegexPathSpec spec = new RegexPathSpec("^/a$"); - assertEquals("Spec.pathSpec","^/a$",spec.getPathSpec()); + assertEquals("Spec.pathSpec","^/a$",spec.getDeclaration()); assertEquals("Spec.pattern","^/a$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",1,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.EXACT,spec.group); @@ -57,7 +57,7 @@ public class RegexPathSpecTest public void testMiddleSpec() { RegexPathSpec spec = new RegexPathSpec("^/rest/([^/]*)/list$"); - assertEquals("Spec.pathSpec","^/rest/([^/]*)/list$",spec.getPathSpec()); + assertEquals("Spec.pathSpec","^/rest/([^/]*)/list$",spec.getDeclaration()); assertEquals("Spec.pattern","^/rest/([^/]*)/list$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",3,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.MIDDLE_GLOB,spec.group); @@ -78,7 +78,7 @@ public class RegexPathSpecTest public void testMiddleSpecNoGrouping() { RegexPathSpec spec = new RegexPathSpec("^/rest/[^/]+/list$"); - assertEquals("Spec.pathSpec","^/rest/[^/]+/list$",spec.getPathSpec()); + assertEquals("Spec.pathSpec","^/rest/[^/]+/list$",spec.getDeclaration()); assertEquals("Spec.pattern","^/rest/[^/]+/list$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",3,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.MIDDLE_GLOB,spec.group); @@ -99,7 +99,7 @@ public class RegexPathSpecTest public void testPrefixSpec() { RegexPathSpec spec = new RegexPathSpec("^/a/(.*)$"); - assertEquals("Spec.pathSpec","^/a/(.*)$",spec.getPathSpec()); + assertEquals("Spec.pathSpec","^/a/(.*)$",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/(.*)$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",2,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.PREFIX_GLOB,spec.group); @@ -117,7 +117,7 @@ public class RegexPathSpecTest public void testSuffixSpec() { RegexPathSpec spec = new RegexPathSpec("^(.*).do$"); - assertEquals("Spec.pathSpec","^(.*).do$",spec.getPathSpec()); + assertEquals("Spec.pathSpec","^(.*).do$",spec.getDeclaration()); assertEquals("Spec.pattern","^(.*).do$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",0,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.SUFFIX_GLOB,spec.group); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java index 7252a9c1b48..fb8e65b25a5 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java @@ -43,13 +43,13 @@ public class ServletPathSpecTest private void assertMatches(ServletPathSpec spec, String path) { - String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(true)); } private void assertNotMatches(ServletPathSpec spec, String path) { - String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(false)); } @@ -87,7 +87,7 @@ public class ServletPathSpecTest public void testDefaultPathSpec() { ServletPathSpec spec = new ServletPathSpec("/"); - assertEquals("Spec.pathSpec","/",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/",spec.getDeclaration()); assertEquals("Spec.pathDepth",-1,spec.getPathDepth()); } @@ -95,7 +95,7 @@ public class ServletPathSpecTest public void testExactPathSpec() { ServletPathSpec spec = new ServletPathSpec("/abs/path"); - assertEquals("Spec.pathSpec","/abs/path",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/abs/path",spec.getDeclaration()); assertEquals("Spec.pathDepth",2,spec.getPathDepth()); assertMatches(spec,"/abs/path"); @@ -125,7 +125,7 @@ public class ServletPathSpecTest public void testNullPathSpec() { ServletPathSpec spec = new ServletPathSpec(null); - assertEquals("Spec.pathSpec","",spec.getPathSpec()); + assertEquals("Spec.pathSpec","",spec.getDeclaration()); assertEquals("Spec.pathDepth",-1,spec.getPathDepth()); } @@ -133,7 +133,7 @@ public class ServletPathSpecTest public void testRootPathSpec() { ServletPathSpec spec = new ServletPathSpec(""); - assertEquals("Spec.pathSpec","",spec.getPathSpec()); + assertEquals("Spec.pathSpec","",spec.getDeclaration()); assertEquals("Spec.pathDepth",-1,spec.getPathDepth()); } @@ -154,7 +154,7 @@ public class ServletPathSpecTest public void testPrefixPathSpec() { ServletPathSpec spec = new ServletPathSpec("/downloads/*"); - assertEquals("Spec.pathSpec","/downloads/*",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/downloads/*",spec.getDeclaration()); assertEquals("Spec.pathDepth",2,spec.getPathDepth()); assertMatches(spec,"/downloads/logo.jpg"); @@ -173,7 +173,7 @@ public class ServletPathSpecTest public void testSuffixPathSpec() { ServletPathSpec spec = new ServletPathSpec("*.gz"); - assertEquals("Spec.pathSpec","*.gz",spec.getPathSpec()); + assertEquals("Spec.pathSpec","*.gz",spec.getDeclaration()); assertEquals("Spec.pathDepth",0,spec.getPathDepth()); assertMatches(spec,"/downloads/distribution.tar.gz"); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java index 7908344e09c..50dcab923ce 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java @@ -34,7 +34,7 @@ public class UriTemplatePathSpecTest { private void assertDetectedVars(UriTemplatePathSpec spec, String... expectedVars) { - String prefix = String.format("Spec(\"%s\")",spec.getPathSpec()); + String prefix = String.format("Spec(\"%s\")",spec.getDeclaration()); assertEquals(prefix + ".variableCount",expectedVars.length,spec.getVariableCount()); assertEquals(prefix + ".variable.length",expectedVars.length,spec.getVariables().length); for (int i = 0; i < expectedVars.length; i++) @@ -45,13 +45,13 @@ public class UriTemplatePathSpecTest private void assertMatches(PathSpec spec, String path) { - String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(true)); } private void assertNotMatches(PathSpec spec, String path) { - String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getPathSpec(),path); + String msg = String.format("!Spec(\"%s\").matches(\"%s\")",spec.getDeclaration(),path); assertThat(msg,spec.matches(path),is(false)); } @@ -59,7 +59,7 @@ public class UriTemplatePathSpecTest public void testDefaultPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/"); - assertEquals("Spec.pathSpec","/",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/",spec.getDeclaration()); assertEquals("Spec.pattern","^/$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",1,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.EXACT,spec.getGroup()); @@ -72,7 +72,7 @@ public class UriTemplatePathSpecTest public void testExactOnePathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a"); - assertEquals("Spec.pathSpec","/a",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a",spec.getDeclaration()); assertEquals("Spec.pattern","^/a$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",1,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.EXACT,spec.getGroup()); @@ -90,7 +90,7 @@ public class UriTemplatePathSpecTest public void testExactPathSpec_TestWebapp() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/deep.thought/"); - assertEquals("Spec.pathSpec","/deep.thought/",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/deep.thought/",spec.getDeclaration()); assertEquals("Spec.pattern","^/deep\\.thought/$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",1,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.EXACT,spec.getGroup()); @@ -106,7 +106,7 @@ public class UriTemplatePathSpecTest public void testExactTwoPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a/b"); - assertEquals("Spec.pathSpec","/a/b",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a/b",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/b$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",2,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.EXACT,spec.getGroup()); @@ -125,7 +125,7 @@ public class UriTemplatePathSpecTest public void testMiddleVarPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a/{var}/c"); - assertEquals("Spec.pathSpec","/a/{var}/c",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a/{var}/c",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/([^/]+)/c$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",3,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.MIDDLE_GLOB,spec.getGroup()); @@ -149,7 +149,7 @@ public class UriTemplatePathSpecTest public void testOneVarPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a/{foo}"); - assertEquals("Spec.pathSpec","/a/{foo}",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a/{foo}",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/([^/]+)$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",2,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.PREFIX_GLOB,spec.getGroup()); @@ -170,7 +170,7 @@ public class UriTemplatePathSpecTest public void testOneVarSuffixPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/{var}/b/c"); - assertEquals("Spec.pathSpec","/{var}/b/c",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/{var}/b/c",spec.getDeclaration()); assertEquals("Spec.pattern","^/([^/]+)/b/c$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",3,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.SUFFIX_GLOB,spec.getGroup()); @@ -194,7 +194,7 @@ public class UriTemplatePathSpecTest public void testTwoVarComplexInnerPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a/{var1}/c/{var2}/e"); - assertEquals("Spec.pathSpec","/a/{var1}/c/{var2}/e",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a/{var1}/c/{var2}/e",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/([^/]+)/c/([^/]+)/e$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",5,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.MIDDLE_GLOB,spec.getGroup()); @@ -217,7 +217,7 @@ public class UriTemplatePathSpecTest public void testTwoVarComplexOuterPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/{var1}/b/{var2}/{var3}"); - assertEquals("Spec.pathSpec","/{var1}/b/{var2}/{var3}",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/{var1}/b/{var2}/{var3}",spec.getDeclaration()); assertEquals("Spec.pattern","^/([^/]+)/b/([^/]+)/([^/]+)$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",4,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.MIDDLE_GLOB,spec.getGroup()); @@ -241,7 +241,7 @@ public class UriTemplatePathSpecTest public void testTwoVarPrefixPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/a/{var1}/{var2}"); - assertEquals("Spec.pathSpec","/a/{var1}/{var2}",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/a/{var1}/{var2}",spec.getDeclaration()); assertEquals("Spec.pattern","^/a/([^/]+)/([^/]+)$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",3,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.PREFIX_GLOB,spec.getGroup()); @@ -264,7 +264,7 @@ public class UriTemplatePathSpecTest public void testVarOnlyPathSpec() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/{var1}"); - assertEquals("Spec.pathSpec","/{var1}",spec.getPathSpec()); + assertEquals("Spec.pathSpec","/{var1}",spec.getDeclaration()); assertEquals("Spec.pattern","^/([^/]+)$",spec.getPattern().pattern()); assertEquals("Spec.pathDepth",1,spec.getPathDepth()); assertEquals("Spec.group",PathSpecGroup.PREFIX_GLOB,spec.getGroup());