From: Artur Signell Date: Wed, 26 Oct 2016 19:35:23 +0000 (+0300) Subject: Serve static files also in servletPath/VAADIN (#14398) X-Git-Tag: 8.0.0.alpha6~36 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1e978a6ba0924c240803543a31d024b7c649f4ce;p=vaadin-framework.git Serve static files also in servletPath/VAADIN (#14398) Change-Id: I6891827a1fb99216d4e286c761d1384a88000604 --- diff --git a/server/src/main/java/com/vaadin/server/VaadinServlet.java b/server/src/main/java/com/vaadin/server/VaadinServlet.java index 42dfde5444..a2bf4fd5b0 100644 --- a/server/src/main/java/com/vaadin/server/VaadinServlet.java +++ b/server/src/main/java/com/vaadin/server/VaadinServlet.java @@ -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; } /** diff --git a/server/src/test/java/com/vaadin/server/VaadinServletTest.java b/server/src/test/java/com/vaadin/server/VaadinServletTest.java index 5d43d315ff..296d4e8c40 100644 --- a/server/src/test/java/com/vaadin/server/VaadinServletTest.java +++ b/server/src/test/java/com/vaadin/server/VaadinServletTest.java @@ -15,8 +15,11 @@ */ 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; + } } diff --git a/uitest/src/main/webapp/WEB-INF/web.xml b/uitest/src/main/webapp/WEB-INF/web.xml index b96257b1e0..31f535e383 100644 --- a/uitest/src/main/webapp/WEB-INF/web.xml +++ b/uitest/src/main/webapp/WEB-INF/web.xml @@ -146,6 +146,15 @@ true + + ResourcesFromServlet + com.vaadin.launcher.ApplicationRunnerServlet + + resources + /servlet-with-resources + + true + @@ -221,6 +230,11 @@ /VAADIN/* + + ResourcesFromServlet + /servlet-with-resources/* + + index.html 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 index 0000000000..92d5795eee --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServletWithResourcesTest.java @@ -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 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 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")); + } + + } + +}