]> source.dussan.org Git - vaadin-framework.git/commitdiff
Serve static files also in servletPath/VAADIN (#14398)
authorArtur Signell <artur@vaadin.com>
Wed, 26 Oct 2016 19:35:23 +0000 (22:35 +0300)
committerVaadin Code Review <review@vaadin.com>
Sat, 29 Oct 2016 07:34:54 +0000 (07:34 +0000)
Change-Id: I6891827a1fb99216d4e286c761d1384a88000604

server/src/main/java/com/vaadin/server/VaadinServlet.java
server/src/test/java/com/vaadin/server/VaadinServletTest.java
uitest/src/main/webapp/WEB-INF/web.xml
uitest/src/test/java/com/vaadin/tests/applicationservlet/ServletWithResourcesTest.java [new file with mode: 0644]

index 42dfde5444d29128ec7177af43dcd7644b11d09a..a2bf4fd5b0cc5d4368545beaa82bd8b576126dd0 100644 (file)
@@ -31,7 +31,6 @@ import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.URLDecoder;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -720,25 +719,9 @@ public class VaadinServlet extends HttpServlet implements Constants {
     private boolean serveStaticResources(HttpServletRequest request,
             HttpServletResponse response) throws IOException, ServletException {
 
-        String pathInfo = request.getPathInfo();
-        if (pathInfo == null) {
-            return false;
-        }
-
-        String decodedRequestURI = URLDecoder.decode(request.getRequestURI(),
-                "UTF-8");
-        if ((request.getContextPath() != null)
-                && (decodedRequestURI.startsWith("/VAADIN/"))) {
-            serveStaticResourcesInVAADIN(decodedRequestURI, request, response);
-            return true;
-        }
-
-        String decodedContextPath = URLDecoder.decode(request.getContextPath(),
-                "UTF-8");
-        if (decodedRequestURI.startsWith(decodedContextPath + "/VAADIN/")) {
-            serveStaticResourcesInVAADIN(
-                    decodedRequestURI.substring(decodedContextPath.length()),
-                    request, response);
+        String filePath = getStaticFilePath(request);
+        if (filePath != null) {
+            serveStaticResourcesInVAADIN(filePath, request, response);
             return true;
         }
 
@@ -1284,8 +1267,25 @@ public class VaadinServlet extends HttpServlet implements Constants {
     }
 
     protected boolean isStaticResourceRequest(HttpServletRequest request) {
-        return request.getRequestURI()
-                .startsWith(request.getContextPath() + "/VAADIN/");
+        return getStaticFilePath(request) != null;
+    }
+
+    protected String getStaticFilePath(HttpServletRequest request) {
+        String pathInfo = request.getPathInfo();
+        if (pathInfo == null) {
+            return null;
+        }
+        // Servlet mapped as /* serves at /VAADIN
+        // Servlet mapped as /foo/bar/* serves at /foo/bar/VAADIN
+        if (pathInfo.startsWith("/VAADIN/")) {
+            return pathInfo;
+        }
+        String servletPrefixedPath = request.getServletPath() + pathInfo;
+        // Servlet mapped as /VAADIN/*
+        if (servletPrefixedPath.startsWith("/VAADIN/")) {
+            return servletPrefixedPath;
+        }
+        return null;
     }
 
     /**
index 5d43d315ff6404b364e2ac7da88820b8fc95eea3..296d4e8c40e69fd7aef5abceddb6807bb91c68e2 100644 (file)
  */
 package com.vaadin.server;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 public class VaadinServletTest {
 
@@ -57,4 +60,77 @@ public class VaadinServletTest {
         Assert.assertEquals("", VaadinServlet
                 .getLastPathParameter("http://myhost.com/a;hello/;b=1,c=2/"));
     }
+
+    @Test
+    public void getStaticFilePath() {
+        VaadinServlet servlet = new VaadinServlet();
+
+        // Mapping: /VAADIN/*
+        // /VAADIN
+        Assert.assertNull(servlet
+                .getStaticFilePath(createServletRequest("/VAADIN", null)));
+        // /VAADIN/ - not really sensible but still interpreted as a resource
+        // request
+        Assert.assertEquals("/VAADIN/", servlet
+                .getStaticFilePath(createServletRequest("/VAADIN", "/")));
+        // /VAADIN/vaadinBootstrap.js
+        Assert.assertEquals("/VAADIN/vaadinBootstrap.js",
+                servlet.getStaticFilePath(createServletRequest("/VAADIN",
+                        "/vaadinBootstrap.js")));
+        // /VAADIN/foo bar.js
+        Assert.assertEquals("/VAADIN/foo bar.js", servlet.getStaticFilePath(
+                createServletRequest("/VAADIN", "/foo bar.js")));
+        // /VAADIN/.. - not normalized and disallowed in this method
+        Assert.assertEquals("/VAADIN/..", servlet
+                .getStaticFilePath(createServletRequest("/VAADIN", "/..")));
+
+        // Mapping: /*
+        // /
+        Assert.assertNull(
+                servlet.getStaticFilePath(createServletRequest("", null)));
+        // /VAADIN
+        Assert.assertNull(
+                servlet.getStaticFilePath(createServletRequest("", "/VAADIN")));
+        // /VAADIN/
+        Assert.assertEquals("/VAADIN/", servlet
+                .getStaticFilePath(createServletRequest("", "/VAADIN/")));
+        // /VAADIN/foo bar.js
+        Assert.assertEquals("/VAADIN/foo bar.js", servlet.getStaticFilePath(
+                createServletRequest("", "/VAADIN/foo bar.js")));
+        // /VAADIN/.. - not normalized and disallowed in this method
+        Assert.assertEquals("/VAADIN/..", servlet
+                .getStaticFilePath(createServletRequest("", "/VAADIN/..")));
+        // /BAADIN/foo.js
+        Assert.assertNull(servlet
+                .getStaticFilePath(createServletRequest("", "/BAADIN/foo.js")));
+
+        // Mapping: /myservlet/*
+        // /myservlet
+        Assert.assertNull(servlet
+                .getStaticFilePath(createServletRequest("/myservlet", null)));
+        // /myservlet/VAADIN
+        Assert.assertNull(servlet.getStaticFilePath(
+                createServletRequest("/myservlet", "/VAADIN")));
+        // /myservlet/VAADIN/
+        Assert.assertEquals("/VAADIN/", servlet.getStaticFilePath(
+                createServletRequest("/myservlet", "/VAADIN/")));
+        // /myservlet/VAADIN/foo bar.js
+        Assert.assertEquals("/VAADIN/foo bar.js", servlet.getStaticFilePath(
+                createServletRequest("/myservlet", "/VAADIN/foo bar.js")));
+        // /myservlet/VAADIN/.. - not normalized and disallowed in this method
+        Assert.assertEquals("/VAADIN/..", servlet.getStaticFilePath(
+                createServletRequest("/myservlet", "/VAADIN/..")));
+        // /myservlet/BAADIN/foo.js
+        Assert.assertNull(servlet.getStaticFilePath(
+                createServletRequest("/myservlet", "/BAADIN/foo.js")));
+
+    }
+
+    private HttpServletRequest createServletRequest(String servletPath,
+            String pathInfo) {
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(request.getServletPath()).thenReturn(servletPath);
+        Mockito.when(request.getPathInfo()).thenReturn(pathInfo);
+        return request;
+    }
 }
index b96257b1e0abd42bc77ec07b3e880a550301cd3c..31f535e383797c28791e1b17b6ea9852a9ddbbd8 100644 (file)
         </init-param>
         <async-supported>true</async-supported>
     </servlet>
+    <servlet>
+        <servlet-name>ResourcesFromServlet</servlet-name>
+        <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
+        <init-param>
+            <param-name>resources</param-name>
+            <param-value>/servlet-with-resources</param-value>
+        </init-param>
+        <async-supported>true</async-supported>
+    </servlet>
 
     <!-- For testing GAE - the deployment script changes this to use GAEVaadinServlet -->
     <servlet>
         <url-pattern>/VAADIN/*</url-pattern>
     </servlet-mapping>
 
+    <servlet-mapping>
+        <servlet-name>ResourcesFromServlet</servlet-name>
+        <url-pattern>/servlet-with-resources/*</url-pattern>
+    </servlet-mapping>
+
     <welcome-file-list>
         <welcome-file>index.html</welcome-file>
     </welcome-file-list>
diff --git a/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServletWithResourcesTest.java b/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServletWithResourcesTest.java
new file mode 100644 (file)
index 0000000..92d5795
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed 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 com.vaadin.tests.applicationservlet;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.tests.components.label.LabelModes;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class ServletWithResourcesTest extends SingleBrowserTest {
+
+    @Override
+    protected Class<?> getUIClass() {
+        return LabelModes.class;
+    }
+
+    @Override
+    protected String getDeploymentPath(Class<?> uiClass) {
+        return super.getDeploymentPath(uiClass).replaceAll("/run/",
+                "/servlet-with-resources/");
+    }
+
+    @Test
+    public void servletServesResources() {
+        openTestURL();
+        Assert.assertEquals("Enabled",
+                $(CheckBoxElement.class).first().getCaption());
+
+        List<WebElement> links = findElements(By.xpath("//head/link"));
+        for (WebElement link : links) {
+            String href = link.getAttribute("href");
+            Assert.assertTrue(
+                    "href '" + href
+                            + "' should contain '/servlet-with-resources/VAADIN'",
+                    href.contains("/servlet-with-resources/VAADIN"));
+        }
+
+        List<WebElement> scripts = findElements(By.xpath("//head/script"));
+        for (WebElement script : scripts) {
+            String src = script.getAttribute("src");
+            Assert.assertTrue(
+                    "src '" + src
+                            + "' should contain '/servlet-with-resources/VAADIN'",
+                    src.contains("/servlet-with-resources/VAADIN"));
+        }
+
+    }
+
+}