FELIX-5109 : Wrong path matching for http whiteboard service
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1715214 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolverFactory.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolverFactory.java
index 16b67c8..9891292 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolverFactory.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolverFactory.java
@@ -22,6 +22,7 @@
import javax.annotation.Nonnull;
import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.service.HttpServiceFactory;
/**
* The path resolver factory creates a path resolver for a pattern.
@@ -55,7 +56,11 @@
{
return new PathMatcher(handler, pattern);
}
- return new ExactAndPathMatcher(handler, pattern);
+ else if ( handler != null && handler.getContextServiceId() == HttpServiceFactory.HTTP_SERVICE_CONTEXT_SERVICE_ID )
+ {
+ return new ExactAndPathMatcher(handler, pattern);
+ }
+ return new ExactMatcher(handler, pattern);
}
public static @Nonnull PathResolver createRegexMatcher(@Nonnull final String regex)
@@ -184,7 +189,7 @@
public ExactAndPathMatcher(final ServletHandler handler, final String pattern)
{
- super(handler, pattern, 4);
+ super(handler, pattern, 5);
this.path = pattern;
this.prefix = pattern.concat("/");
}
@@ -221,18 +226,63 @@
}
}
+ public static final class ExactMatcher extends AbstractMatcher
+ {
+ private final String path;
+
+ public ExactMatcher(final ServletHandler handler, final String pattern)
+ {
+ super(handler, pattern, 5);
+ this.path = pattern;
+ }
+
+ @Override
+ public PathResolution resolve(final String uri) {
+ if ( uri.equals(this.path) )
+ {
+ final PathResolution pr = new PathResolution();
+ pr.servletPath = uri;
+ pr.pathInfo = null;
+ pr.requestURI = uri;
+ pr.handler = this.getServletHandler();
+
+ return pr;
+ }
+ return null;
+ }
+
+ @Override
+ public int getOrdering()
+ {
+ return this.path.length();
+ }
+ }
+
public static final class PathMatcher extends AbstractMatcher
{
private final String prefix;
+ private final String path;
+
public PathMatcher(final ServletHandler handler, final String pattern)
{
super(handler, pattern, 4);
this.prefix = pattern.substring(0, pattern.length() - 1);
+ this.path = pattern.substring(0, pattern.length() - 2);
}
@Override
public PathResolution resolve(final String uri) {
+ if ( uri.equals(this.path) )
+ {
+ final PathResolution pr = new PathResolution();
+ pr.servletPath = this.path;
+ pr.pathInfo = null;
+ pr.requestURI = uri;
+ pr.handler = this.getServletHandler();
+
+ return pr;
+ }
if ( uri.startsWith(this.prefix) )
{
final PathResolution pr = new PathResolution();
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PathResolverFactoryTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PathResolverFactoryTest.java
index d110440..46dbe23 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PathResolverFactoryTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PathResolverFactoryTest.java
@@ -62,4 +62,17 @@
assertResult(pr, "/foo/bar", "/foo/bar", null);
assertResult(pr, "/foo", "/foo", null);
}
+
+ @Test public void testPathMatcher()
+ {
+ final PathResolver pr = PathResolverFactory.createPatternMatcher(null, "/*");
+ assertNotNull(pr);
+
+ assertResult(pr, "/foo", "", "/foo");
+ assertResult(pr, "/foo/bar", "", "/foo/bar");
+
+ assertResult(pr, "/", "", "/");
+
+ assertResult(pr, "", "", null);
+ }
}
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/ServletRegistryTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/ServletRegistryTest.java
index a158c7a..3791fe3 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/ServletRegistryTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/ServletRegistryTest.java
@@ -26,6 +26,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -171,6 +175,20 @@
assertEmpty(dto, holder);
}
+ @Test public void testMatcherOrdering() throws InvalidSyntaxException
+ {
+ final ServletHandler h1 = createServletHandler(1L, 0, "/foo");
+ final ServletHandler h2 = createServletHandler(2L, 0, "/foo/*");
+
+ final List<PathResolver> resolvers = new ArrayList<PathResolver>();
+ resolvers.add(PathResolverFactory.createPatternMatcher(h1, "/foo"));
+ resolvers.add(PathResolverFactory.createPatternMatcher(h2, "/foo/*"));
+
+ Collections.sort(resolvers);
+ assertEquals("/foo", resolvers.get(0).getPattern());
+ assertEquals("/foo/*", resolvers.get(1).getPattern());
+ }
+
@Test public void testServletOrdering() throws InvalidSyntaxException
{
final ServletHandler h1 = createServletHandler(1L, 0, "/foo");
@@ -195,16 +213,16 @@
assertNull(pr);
pr = reg.resolve("/foo/bar");
- assertEquals("/foo/*", pr.patterns[0]);
- assertEquals(h2, pr.handler);
+ assertEquals("/foo", pr.patterns[0]);
+ assertEquals(h1, pr.handler);
pr = reg.resolve("/foo/rsrc");
assertEquals("/foo/rsrc", pr.patterns[0]);
assertEquals(h3, pr.handler);
pr = reg.resolve("/foo/rsrc/some");
- assertEquals("/foo/rsrc/*", pr.patterns[0]);
- assertEquals(h4, pr.handler);
+ assertEquals("/foo/rsrc", pr.patterns[0]);
+ assertEquals(h3, pr.handler);
pr = reg.resolve("/other");
assertEquals("/other", pr.patterns[0]);
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/ServletPatternTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/ServletPatternTest.java
index a91df7d..e8cfb30 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/ServletPatternTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/ServletPatternTest.java
@@ -257,4 +257,18 @@
assertTrue(initLatch.await(5, TimeUnit.SECONDS));
assertContent("servlet2", createURL("/a/b/test/servlet"));
}
+
+ @Test
+ public void pathMatchingTest() throws Exception
+ {
+ setupLatches(1);
+
+ setupContext("contextA", "/a");
+
+ setupServlet("servlet1", new String[]{ "/servlet/*" }, 1, "contextA");
+
+ assertTrue(initLatch.await(5, TimeUnit.SECONDS));
+ assertContent("servlet1", createURL("/a/servlet/foo"));
+ assertContent("servlet1", createURL("/a/servlet"));
+ }
}