james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rouaz...@apache.org
Subject [3/5] james-project git commit: JAMES-1814 Encode Content-Disposition header in download servlet when necessary
Date Thu, 22 Sep 2016 07:47:33 GMT
JAMES-1814 Encode Content-Disposition header in download servlet when necessary


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/abb21de1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/abb21de1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/abb21de1

Branch: refs/heads/master
Commit: abb21de13fefe2c99626d2178f99a7002fd2b4f8
Parents: 7443396
Author: Laura Royet <lroyet@linagora.com>
Authored: Wed Sep 21 12:20:48 2016 +0200
Committer: Laura Royet <lroyet@linagora.com>
Committed: Wed Sep 21 12:20:48 2016 +0200

----------------------------------------------------------------------
 .../integration/cucumber/DownloadStepdefs.java  | 26 +++++++++++++++++++-
 .../test/resources/cucumber/DownloadGet.feature |  6 +++++
 .../org/apache/james/jmap/DownloadServlet.java  | 14 +++++++++--
 3 files changed, 43 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/abb21de1/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
index 6ef8a03..d000bb3 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
@@ -41,7 +41,9 @@ import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.jmap.model.AttachmentAccessToken;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mime4j.codec.DecoderUtil;
 
+import com.google.common.base.CharMatcher;
 import com.google.common.base.Charsets;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
@@ -63,6 +65,7 @@ public class DownloadStepdefs {
     private static final String INVALID_ATTACHMENT_TOKEN = "usera@domain.tld_"
             + "2015-06-29T13:41:22.124Z_"
             + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";
+    private static final String UTF8_CONTENT_DIPOSITION_START = "Content-Disposition: attachment;
filename*=\"";
 
     private final UserStepdefs userStepdefs;
     private final MainStepdefs mainStepdefs;
@@ -330,6 +333,27 @@ public class DownloadStepdefs {
 
     @Then("^the attachment is named \"([^\"]*)\"$")
     public void assertContentDisposition(String name) throws IOException {
-        assertThat(response.getHeaders("Content-Disposition")).extracting(Header::toString).containsExactly("Content-Disposition:
attachment; filename=\"" + name + "\"");
+        if (!CharMatcher.ASCII.matchesAllOf(name)) {
+            assertEncodedFilenameMatches(name);
+        } else {
+            assertThat(response.getFirstHeader("Content-Disposition").getValue()).isEqualTo("attachment;
filename=\"" + name + "\"");
+        }
+    }
+
+    private void assertEncodedFilenameMatches(String name) {
+        String contentDispositionHeader = response.getHeaders("Content-Disposition")[0].toString();
+        assertThat(contentDispositionHeader).startsWith(UTF8_CONTENT_DIPOSITION_START);
+
+        String expectedFilename = decode(extractFilename(contentDispositionHeader));
+        assertThat(name).isEqualTo(expectedFilename);
+    }
+
+    private String extractFilename(String contentDispositionHeader) {
+        return contentDispositionHeader.substring(UTF8_CONTENT_DIPOSITION_START.length(),

+                contentDispositionHeader.length() - 1);
+    }
+
+    private String decode(String name) {
+        return DecoderUtil.decodeEncodedWords(name, Charsets.UTF_8);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/abb21de1/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
index 6772e4f..82828d1 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
@@ -22,3 +22,9 @@ Feature: Download GET
     When "username@domain.tld" downloads "2" with "myFileName.txt" name
     Then the user should receive that attachment
     And the attachment is named "myFileName.txt"
+
+  Scenario: Getting an attachment previously stored with a non ASCII name
+    Given "username@domain.tld" mailbox "inbox" contains a message "1" with an attachment
"2"
+    When "username@domain.tld" downloads "2" with "ديناصور.odt" name
+    Then the user should receive that attachment
+    And the attachment is named "ديناصور.odt"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/abb21de1/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
index 0d140e6..45f5dcc 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
@@ -41,10 +41,13 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mime4j.codec.EncoderUtil;
+import org.apache.james.mime4j.codec.EncoderUtil.Usage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.CharMatcher;
 
 public class DownloadServlet extends HttpServlet {
 
@@ -126,10 +129,17 @@ public class DownloadServlet extends HttpServlet {
     }
 
     private void addContentDispositionHeader(Optional<String> optionalName, HttpServletResponse
resp) {
-        optionalName.ifPresent(name -> resp.addHeader("Content-Disposition", "attachment;
filename=\"" + name + "\""));
+        optionalName.ifPresent(name -> addContentDispositionHeaderRegardingEncoding(name,
resp));
+    }
+
+    private void addContentDispositionHeaderRegardingEncoding(String name, HttpServletResponse
resp) {
+        if (CharMatcher.ASCII.matchesAllOf(name)) {
+            resp.addHeader("Content-Disposition", "attachment; filename=\"" + name + "\"");
+        } else {
+            resp.addHeader("Content-Disposition", "attachment; filename*=\"" + EncoderUtil.encodeEncodedWord(name,
Usage.TEXT_TOKEN) + "\"");
+        }
     }
 
-    
     private MailboxSession getMailboxSession(HttpServletRequest req) {
         return (MailboxSession) req.getAttribute(AuthenticationFilter.MAILBOX_SESSION);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message