Skip to content

Commit

Permalink
Serve static files also in servletPath/VAADIN (#14398)
Browse files Browse the repository at this point in the history
Change-Id: I6891827a1fb99216d4e286c761d1384a88000604
  • Loading branch information
Artur- authored and Vaadin Code Review committed Oct 29, 2016
1 parent 334b3f0 commit 1e978a6
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 22 deletions.
44 changes: 22 additions & 22 deletions server/src/main/java/com/vaadin/server/VaadinServlet.java
Expand Up @@ -31,7 +31,6 @@
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
Expand Down Expand Up @@ -720,25 +719,9 @@ public static String getDefaultTheme() {
private boolean serveStaticResources(HttpServletRequest request, private boolean serveStaticResources(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException { HttpServletResponse response) throws IOException, ServletException {


String pathInfo = request.getPathInfo(); String filePath = getStaticFilePath(request);
if (pathInfo == null) { if (filePath != null) {
return false; serveStaticResourcesInVAADIN(filePath, request, response);
}

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);
return true; return true;
} }


Expand Down Expand Up @@ -1284,8 +1267,25 @@ protected RequestType getRequestType(VaadinServletRequest request) {
} }


protected boolean isStaticResourceRequest(HttpServletRequest request) { protected boolean isStaticResourceRequest(HttpServletRequest request) {
return request.getRequestURI() return getStaticFilePath(request) != null;
.startsWith(request.getContextPath() + "/VAADIN/"); }

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;
} }


/** /**
Expand Down
76 changes: 76 additions & 0 deletions server/src/test/java/com/vaadin/server/VaadinServletTest.java
Expand Up @@ -15,8 +15,11 @@
*/ */
package com.vaadin.server; package com.vaadin.server;


import javax.servlet.http.HttpServletRequest;

import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;


public class VaadinServletTest { public class VaadinServletTest {


Expand Down Expand Up @@ -57,4 +60,77 @@ public void testGetLastPathParameter() {
Assert.assertEquals("", VaadinServlet Assert.assertEquals("", VaadinServlet
.getLastPathParameter("http://myhost.com/a;hello/;b=1,c=2/")); .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;
}
} }
14 changes: 14 additions & 0 deletions uitest/src/main/webapp/WEB-INF/web.xml
Expand Up @@ -146,6 +146,15 @@
</init-param> </init-param>
<async-supported>true</async-supported> <async-supported>true</async-supported>
</servlet> </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 --> <!-- For testing GAE - the deployment script changes this to use GAEVaadinServlet -->
<servlet> <servlet>
Expand Down Expand Up @@ -221,6 +230,11 @@
<url-pattern>/VAADIN/*</url-pattern> <url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping> </servlet-mapping>


<servlet-mapping>
<servlet-name>ResourcesFromServlet</servlet-name>
<url-pattern>/servlet-with-resources/*</url-pattern>
</servlet-mapping>

<welcome-file-list> <welcome-file-list>
<welcome-file>index.html</welcome-file> <welcome-file>index.html</welcome-file>
</welcome-file-list> </welcome-file-list>
Expand Down
@@ -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"));
}

}

}

0 comments on commit 1e978a6

Please sign in to comment.