FELIX-1713: Fixed getPathInfo() bug

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@822505 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
index 11c7a26..e2e14a8 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
@@ -21,7 +21,6 @@
 import javax.servlet.ServletConfig;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletRequestWrapper;
 import org.apache.felix.http.base.internal.context.ExtServletContext;
 import java.io.IOException;
 
@@ -89,7 +88,7 @@
                 res.sendError(HttpServletResponse.SC_FORBIDDEN);
             }
         } else {
-            this.servlet.service(new RequestWrapper(req), res);
+            this.servlet.service(new ServletHandlerRequest(req, this.alias), res);
         }
     }
 
@@ -97,47 +96,4 @@
     {
         return other.alias.length() - this.alias.length();
     }    
-
-    private final class RequestWrapper
-        extends HttpServletRequestWrapper
-    {
-        private String pathInfo;
-        private boolean pathInfoComputed = false;
-
-        public RequestWrapper(HttpServletRequest req)
-        {
-            super(req);
-        }
-
-        @Override
-        public String getPathInfo()
-        {
-            if (!this.pathInfoComputed) {
-                final int servletPathLength = getServletPath().length();
-                this.pathInfo = getRequestURI().substring(getContextPath().length()).replaceAll("[/]{2,}", "/")
-                    .substring(servletPathLength);
-
-                if ("".equals(this.pathInfo) && servletPathLength != 0) {
-                    this.pathInfo = null;
-                }
-
-                this.pathInfoComputed = true;
-            }
-
-            return this.pathInfo;
-        }
-
-        @Override
-        public String getPathTranslated()
-        {
-            final String info = getPathInfo();
-            return (null == info) ? null : getRealPath(info);
-        }
-
-        @Override
-        public String getServletPath()
-        {
-            return alias;
-        }
-    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java
new file mode 100644
index 0000000..8604960
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.handler;
+
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletRequest;
+
+final class ServletHandlerRequest
+    extends HttpServletRequestWrapper
+{
+    private final String alias;
+    private String pathInfo;
+    private boolean pathInfoCalculated = false;
+
+    public ServletHandlerRequest(HttpServletRequest req, String alias)
+    {
+        super(req);
+        this.alias = alias;
+    }
+
+    @Override
+    public String getPathInfo()
+    {
+        if (!this.pathInfoCalculated) {
+            this.pathInfo = calculatePathInfo();
+            this.pathInfoCalculated = true;
+        }
+        
+        return this.pathInfo;
+    }
+
+    @Override
+    public String getPathTranslated()
+    {
+        final String info = getPathInfo();
+        return (null == info) ? null : getRealPath(info);
+    }
+
+    @Override
+    public String getServletPath()
+    {
+        return this.alias;
+    }
+
+    private String calculatePathInfo()
+    {
+        final int servletPathLength = getServletPath().length();
+        final String contextPath = getContextPath();
+        
+        String pathInfo = getRequestURI();
+        pathInfo = pathInfo.substring(contextPath.length());
+        pathInfo = pathInfo.replaceAll("[/]{2,}", "/");
+        pathInfo = pathInfo.substring(servletPathLength);
+
+        int qmarkPos = pathInfo.indexOf('?');
+        if (qmarkPos > 0) {
+            pathInfo = pathInfo.substring(0, qmarkPos);
+        }
+
+        if ("".equals(pathInfo) && servletPathLength != 0) {
+            pathInfo = null;
+        }
+
+        if (pathInfo != null && !pathInfo.startsWith("/")) {
+            pathInfo = "/" + pathInfo;
+        }
+
+        return pathInfo;
+    }
+}
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequestTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequestTest.java
new file mode 100644
index 0000000..5c87599
--- /dev/null
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequestTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.handler;
+
+import org.mockito.Mockito;
+import org.junit.Test;
+import org.junit.Assert;
+import org.junit.Before;
+import javax.servlet.http.HttpServletRequest;
+
+public class ServletHandlerRequestTest
+{
+    private HttpServletRequest req1;
+    private HttpServletRequest req2;
+
+    @Before
+    public void setUp()
+    {
+        HttpServletRequest superReq = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(superReq.getContextPath()).thenReturn("/mycontext");
+        Mockito.when(superReq.getRequestURI()).thenReturn("/mycontext/request/to/resource");
+        this.req1 = new ServletHandlerRequest(superReq, "/");
+
+        superReq = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(superReq.getContextPath()).thenReturn("/mycontext");
+        Mockito.when(superReq.getRequestURI()).thenReturn("/mycontext/myservlet/request/to/resource?param=value");
+        this.req2 = new ServletHandlerRequest(superReq, "/myservlet");
+    }
+
+    @Test
+    public void testPathInfo()
+    {
+        Assert.assertEquals("/request/to/resource", this.req1.getPathInfo());
+        Assert.assertEquals("/request/to/resource", this.req2.getPathInfo());
+    }
+}