SLING-3119 - handle path-based bypass in doFilter instead of using regexp

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1526908 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index aeb88a2..1bfba9b 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -29,6 +29,7 @@
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.felix.scr.annotations.Activate;
@@ -95,6 +96,16 @@
             return;
         }
         
+        // Bypass for the managerRoot path
+        if(request instanceof HttpServletRequest) {
+            final String pathInfo = ((HttpServletRequest)request).getPathInfo();
+            if(managerRoot != null && managerRoot.length() > 0 && pathInfo.startsWith(managerRoot)) {
+                log.debug("Bypassing filter for path {} which starts with {}", pathInfo, managerRoot);
+                chain.doFilter(request, sr);
+                return;
+            }
+        }
+        
         updateProviders();
         
         final StringBuilder sb = new StringBuilder();
@@ -165,7 +176,7 @@
         if(defaultFilterActive) {
             enable();
         }
-        log.info("Activated, enabled={}", isEnabled());
+        log.info("Activated, enabled={}, managerRoot={}", isEnabled(), managerRoot);
     }
     
     @Deactivate
@@ -179,7 +190,7 @@
     
     public synchronized void enable() {
         if(filterServiceRegistration == null) {
-            final String pattern = "^(?!"+ managerRoot +")(.+)";
+            final String pattern = "/";
             final Hashtable<String, Object> params = new Hashtable<String, Object>();
             params.put(Constants.SERVICE_RANKING, 0x9000); // run before RequestLoggerFilter (0x8000)
             params.put("filter.scope", "REQUEST");
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 9fd25c2..fb80d66 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -28,6 +28,8 @@
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -121,6 +123,8 @@
     private StringWriter messageWriter;
     private AtomicInteger activeFilterCount;
     private ServiceRegistration serviceRegistration;
+    private String requestPath;
+    private static final String CONSOLE_ROOT = "/test/system/console";
 
     @Before
     public void setup() {
@@ -131,6 +135,7 @@
         chain = mockery.mock(FilterChain.class);
         serviceRegistration = mockery.mock(ServiceRegistration.class);
         filter = new TestFilterImpl();
+        requestPath = "/NO_PATH_YET";
     }
     
     private void setProvider(final TestProvider provider) throws Exception {
@@ -170,7 +175,9 @@
             will(returnValue(providerRefs));
             allowing(bundleContext).getService(with(any(ServiceReference.class)));
             will(returnValue(provider));
-            allowing(bundleContext).getProperty(with(any(String.class)));
+            
+            allowing(bundleContext).getProperty(with("felix.webconsole.manager.root"));
+            will(returnValue(CONSOLE_ROOT));
 
             allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
             will(new DoAllAction(
@@ -189,11 +196,20 @@
             
             allowing(serviceRegistration).unregister();
             will(new ChangeInteger(activeFilterCount, false));
+            
+            allowing(request).getPathInfo();
+            will(returnValue(getRequestPath()));
+            
+            allowing(chain).doFilter(with(any(ServletRequest.class)), with(any(ServletResponse.class)));
         }});
         
         filter.setup(componentContext);
     }
     
+    private String getRequestPath() {
+        return requestPath;
+    }
+    
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
         lastReturnedStatus = -1;
         
@@ -216,6 +232,20 @@
     }
 
     @Test
+    public void testBypassRoot() throws Exception {
+        requestPath = CONSOLE_ROOT;
+        setProvider(null);
+        assertRequest(-1, "");
+    }
+
+    @Test
+    public void testBypassSubpath() throws Exception {
+        requestPath = CONSOLE_ROOT + "/something";
+        setProvider(null);
+        assertRequest(-1, "");
+    }
+
+    @Test
     public void testDisabling() throws Exception {
         setProvider(null);
         assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());