summaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorMarco Collovati <mcollovati@gmail.com>2018-05-09 10:47:58 +0200
committerIlia Motornyi <elmot@vaadin.com>2018-05-09 11:47:58 +0300
commit16e394956f6150928f7eeb20c4650ee504602401 (patch)
tree47fa2ef544f3df6e27f94c0b732c199c27bbd37f /server/src
parent977affb7b8633a7bee43d2fd40a86de21c62492e (diff)
downloadvaadin-framework-16e394956f6150928f7eeb20c4650ee504602401.tar.gz
vaadin-framework-16e394956f6150928f7eeb20c4650ee504602401.zip
URL encode file name in GlobalResourceHandler (#10751)
Fixes #10747
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/com/vaadin/server/GlobalResourceHandler.java13
-rw-r--r--server/src/test/java/com/vaadin/server/GlobalResourceHandlerTest.java68
2 files changed, 77 insertions, 4 deletions
diff --git a/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java b/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java
index 4e07bdcd3b..1d1ffc3467 100644
--- a/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java
+++ b/server/src/main/java/com/vaadin/server/GlobalResourceHandler.java
@@ -16,6 +16,7 @@
package com.vaadin.server;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
@@ -26,8 +27,6 @@ import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.servlet.http.HttpServletResponse;
-
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.ui.LegacyComponent;
import com.vaadin.ui.UI;
@@ -96,7 +95,7 @@ public class GlobalResourceHandler implements RequestHandler {
oldInstances = CurrentInstance.setCurrent(ui);
ConnectorResource resource;
if (LEGACY_TYPE.equals(type)) {
- resource = legacyResources.get(key);
+ resource = legacyResources.get(urlEncodedKey(key));
} else {
return error(request, response, "Unknown global resource type "
+ type + " in requested path " + pathInfo);
@@ -123,6 +122,12 @@ public class GlobalResourceHandler implements RequestHandler {
return true;
}
+
+ private String urlEncodedKey(String key) {
+ // getPathInfo return path decoded but without decoding plus as spaces
+ return ResourceReference.encodeFileName(key.replace("+", " "));
+ }
+
/**
* Registers a resource to be served with a global URL.
* <p>
@@ -147,7 +152,7 @@ public class GlobalResourceHandler implements RequestHandler {
+ Integer.toString(nextLegacyId++);
String filename = connectorResource.getFilename();
if (filename != null && !filename.isEmpty()) {
- uri += '/' + filename;
+ uri += '/' + ResourceReference.encodeFileName(filename);
}
legacyResourceKeys.put(connectorResource, uri);
legacyResources.put(uri, connectorResource);
diff --git a/server/src/test/java/com/vaadin/server/GlobalResourceHandlerTest.java b/server/src/test/java/com/vaadin/server/GlobalResourceHandlerTest.java
new file mode 100644
index 0000000000..55663148d9
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/GlobalResourceHandlerTest.java
@@ -0,0 +1,68 @@
+package com.vaadin.server;
+
+import java.io.IOException;
+
+import com.vaadin.tests.util.MockUI;
+import com.vaadin.ui.LegacyComponent;
+import com.vaadin.ui.UI;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class GlobalResourceHandlerTest {
+
+ @Test
+ public void globalResourceHandlerShouldWorkWithEncodedFilename() throws IOException {
+ assertEncodedFilenameIsHandled("simple.txt", "simple.txt");
+ assertEncodedFilenameIsHandled("with spaces.txt", "with+spaces.txt");
+ assertEncodedFilenameIsHandled("with # hash.txt", "with+%23+hash.txt");
+ assertEncodedFilenameIsHandled("with ; semicolon.txt", "with+%3B+semicolon.txt");
+ assertEncodedFilenameIsHandled("with , comma.txt", "with+%2C+comma.txt");
+
+ // ResourceReference.encodeFileName does not encode slashes and backslashes
+ // See comment inside2 method for more details
+ assertEncodedFilenameIsHandled("with \\ backslash.txt", "with+\\+backslash.txt");
+ assertEncodedFilenameIsHandled("with / slash.txt", "with+/+slash.txt");
+ }
+
+ private void assertEncodedFilenameIsHandled(String filename, String expectedFilename) throws IOException {
+ DownloadStream stream = mock(DownloadStream.class);
+ ConnectorResource resource = mock(ConnectorResource.class);
+ when(resource.getFilename()).thenReturn(filename);
+ when(resource.getStream()).thenReturn(stream);
+
+ UI ui = new MockUI() {
+ @Override
+ public int getUIId() {
+ return 0;
+ }
+ };
+ ClientConnector connector = mock(LegacyComponent.class);
+ when(connector.getUI()).thenReturn(ui);
+
+ GlobalResourceHandler handler = new GlobalResourceHandler();
+ handler.register(resource, connector);
+
+ // Verify that file name has been encoded
+ String uri = handler.getUri(connector, resource);
+ assertThat(uri, endsWith("/" + expectedFilename));
+
+ VaadinSession session = mock(VaadinSession.class);
+ VaadinRequest request = mock(VaadinRequest.class);
+ VaadinResponse response = mock(VaadinResponse.class);
+
+ // getPathInfo return path decoded but without decoding plus as spaces
+ when(request.getPathInfo()).thenReturn("APP/global/0/legacy/0/"+ filename.replace(" ", "+"));
+ when(session.getUIById(anyInt())).thenReturn(ui);
+
+ // Verify that decoded path info is correctly handled
+ assertTrue("Request not handled", handler.handleRequest(session, request, response));
+ verify(stream).writeResponse(request, response);
+ }
+}