diff options
author | Artur Signell <artur@vaadin.com> | 2016-10-26 22:35:23 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-10-29 07:34:54 +0000 |
commit | 1e978a6ba0924c240803543a31d024b7c649f4ce (patch) | |
tree | 4ebe5a576e2b4c05417b0822c8becb91bd091130 | |
parent | 334b3f0a4b393f274d171dddc359be605c2cd1b1 (diff) | |
download | vaadin-framework-1e978a6ba0924c240803543a31d024b7c649f4ce.tar.gz vaadin-framework-1e978a6ba0924c240803543a31d024b7c649f4ce.zip |
Serve static files also in servletPath/VAADIN (#14398)
Change-Id: I6891827a1fb99216d4e286c761d1384a88000604
4 files changed, 180 insertions, 22 deletions
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 @@ </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> @@ -221,6 +230,11 @@ <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 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<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")); + } + + } + +} |