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;
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;
}
}
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;
}
/**
*/
package com.vaadin.server;
+import javax.servlet.http.HttpServletRequest;
+
import org.junit.Assert;
import org.junit.Test;
+import org.mockito.Mockito;
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;
+ }
}
</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>
--- /dev/null
+/*
+ * 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"));
+ }
+
+ }
+
+}