You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/05/10 03:27:08 UTC

[james-project] 07/07: JAMES-2744 James download should provide Content-Type header

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit e7d55850526ca94f6a86b63fd47dd2aad7518108
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu May 2 17:26:33 2019 +0700

    JAMES-2744 James download should provide Content-Type header
---
 .../org/apache/james/util/InputStreamUtils.java    | 34 ++++++++++++++
 .../apache/james/util/InputStreamUtilsTest.java    | 53 ++++++++++++++++++++++
 .../integration/cucumber/DownloadStepdefs.java     | 22 ++++++---
 .../test/resources/cucumber/DownloadGet.feature    |  4 +-
 .../src/test/resources/eml/oneAttachment-part1.eml | 30 ++++++++++++
 .../src/test/resources/eml/oneAttachment-part2.eml |  9 ++++
 .../org/apache/james/jmap/DownloadServlet.java     |  1 +
 7 files changed, 145 insertions(+), 8 deletions(-)

diff --git a/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
new file mode 100644
index 0000000..d522965
--- /dev/null
+++ b/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
@@ -0,0 +1,34 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.james.util;
+
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+public class InputStreamUtils {
+    public static InputStream concat(InputStream inputStream, InputStream... additionalInputStreams) {
+        Stream<InputStream> inputStreams = Stream.concat(Stream.of(inputStream), Arrays.stream(additionalInputStreams));
+
+        return inputStreams.reduce(SequenceInputStream::new)
+            .get();
+    }
+}
diff --git a/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
new file mode 100644
index 0000000..7ed1f97
--- /dev/null
+++ b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.james.util;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.jupiter.api.Test;
+
+import com.google.common.primitives.Bytes;
+
+class InputStreamUtilsTest {
+    private static final byte[] CONTENT_1 = "content1".getBytes(StandardCharsets.UTF_8);
+    private static final byte[] CONTENT_2 = "content2".getBytes(StandardCharsets.UTF_8);
+    private static final byte[] EMPTY = "".getBytes(StandardCharsets.UTF_8);
+
+    @Test
+    void concatShouldNoopWhenSingleArgument() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1)))
+            .hasSameContentAs(new ByteArrayInputStream(CONTENT_1));
+    }
+
+    @Test
+    void concatShouldReturnConcatenatedStreams() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1), new ByteArrayInputStream(CONTENT_2)))
+            .hasSameContentAs(new ByteArrayInputStream(Bytes.concat(CONTENT_1, CONTENT_2)));
+    }
+
+    @Test
+    void concatShouldNoopWhenEmpty() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1), new ByteArrayInputStream(EMPTY)))
+            .hasSameContentAs(new ByteArrayInputStream(CONTENT_1));
+    }
+}
\ No newline at end of file
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 b1450a0..8abff9d 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
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
@@ -49,6 +50,7 @@ import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mime4j.codec.DecoderUtil;
+import org.apache.james.util.InputStreamUtils;
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.MoreObjects;
@@ -126,6 +128,20 @@ public class DownloadStepdefs {
         retrieveAndSaveAttachmentDetails(user, messageId, attachmentId, composedMessageId);
     }
 
+    @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an attachment \"([^\"]*)\" having \"([^\"]*)\" contentType$")
+    public void appendMessageWithAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId, String contentType) throws Throwable {
+        MailboxPath mailboxPath = MailboxPath.forUser(user, mailbox);
+
+        InputStream message = InputStreamUtils.concat(
+            ClassLoader.getSystemResourceAsStream("eml/oneAttachment-part1.eml"),
+            new ByteArrayInputStream(contentType.getBytes(StandardCharsets.UTF_8)),
+            ClassLoader.getSystemResourceAsStream("eml/oneAttachment-part2.eml"));
+
+        ComposedMessageId composedMessageId = mainStepdefs.mailboxProbe.appendMessage(user, mailboxPath, AppendCommand.from(message));
+
+        retrieveAndSaveAttachmentDetails(user, messageId, attachmentId, composedMessageId);
+    }
+
     @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an inlined attachment \"([^\"]*)\"$")
     public void appendMessageWithInlinedAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId) throws Throwable {
         MailboxPath mailboxPath = MailboxPath.forUser(user, mailbox);
@@ -456,12 +472,6 @@ public class DownloadStepdefs {
         assertThat(response.getFirstHeader("Content-Length").getValue()).isEqualTo(String.valueOf(size));
     }
 
-    @Then("^there is no Content-Type$")
-    public void assertNoContentType() {
-        assertThat(response.getFirstHeader("Content-Type"))
-            .isNull();
-    }
-
     @Then("^the Content-Type is \"([^\"]*)\"$")
     public void assertContentType(String contentType) {
         assertThat(response.getFirstHeader("Content-Type").getValue()).isEqualTo(contentType);
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 4b7c889..2639d86 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
@@ -51,10 +51,10 @@ Feature: Download GET
     And the attachment is named "ديناصور.odt"
 
   Scenario: Getting an attachment with a specified Content-Type
-    Given "alice@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
+    Given "alice@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2" having "application/pdf" contentType
     When "alice@domain.tld" downloads "2" with "myFileName.txt" name
     Then she can read that blob
-    And there is no Content-Type
+    And the Content-Type is "application/pdf"
 
   @BasicFeature
   Scenario: Getting a message blob previously stored
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml
new file mode 100644
index 0000000..1c7df76
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml
@@ -0,0 +1,30 @@
+Mail content:
+To: "=?utf-8?B?UmFuaSBBc3NhZg==?=" <ra...@jri.obm.lng.org>
+Subject: =?utf-8?B?VHIuIDogUGhvdG9zICE=?=
+Importance: Normal
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+	boundary="----=_Part_0_1330682067197"
+
+------=_Part_0_1330682067197
+Content-Type: multipart/alternative;
+	boundary="----=_Part_2_1330682067197"
+
+------=_Part_2_1330682067197
+Content-Type: text/plain;
+	charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+Content of part 1-1
+------=_Part_2_1330682067197
+Content-Type: text/html;
+	charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<b>Content of part 1-2</b>
+------=_Part_2_1330682067197--
+
+------=_Part_0_1330682067197
+Content-Type:
\ No newline at end of file
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml
new file mode 100644
index 0000000..2e81c80
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml
@@ -0,0 +1,9 @@
+
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+	filename="gimp.png"
+
+iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAALxklEQVR4Ae2Xe0xUZ97H5X4RiyAXEARURBSYCzNnLjMwwAx3huGOIBcUFJERAUVRq+KlwHABFdu+b9+0766x1W21ttnUtE3rul6aGNtm3XbdWncjaa3VXrZRK6IgfPd3Tp6wOGmyo0v/cOMknxwy5xzO7/P8LueZaWlpaU80TwWeCvy3CcRwXJlUqp39RApIOE4i5hQPxBz30hMpIJIrjktkseMimfzPUyoglilTf/XVl8u1Ik4xrOJEEMu4wSkVEMmVZ6VSTeivFXy0TDZfIlfc0qil0KpIQM59P6UCUk71lVShPD1t2jT7qQ4+Sq32prq/GhfHjSXFSxGvEfMCQ1MsoLzOadT3pArFwBQ3LSdRqK4mJyfcz0xRwaCLRVKcBDEybmxqBRTKH8uXpEOj0/1MD3wuMTHR8T9adY4LoOD3KuPj7xYVGlGYo0e6 [...]
+
+------=_Part_0_1330682067197--
+
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 6e2b272..ca317fd 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
@@ -127,6 +127,7 @@ public class DownloadServlet extends HttpServlet {
 
             addContentDispositionHeader(downloadPath.getName(), resp);
             resp.setHeader("Content-Length", String.valueOf(blob.getSize()));
+            resp.setHeader("Content-Type", blob.getContentType());
             resp.setStatus(SC_OK);
             IOUtils.copy(blob.getStream(), resp.getOutputStream());
         } catch (BlobNotFoundException e) {


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