Repository: james-project
Updated Branches:
  refs/heads/master 76cabea09 -> 9e1ccb37f


JAMES-1913 Extract message content from multipart when inlined text attachment


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

Branch: refs/heads/master
Commit: 8e95555710c1d947534e146b0fcef0926b6c1433
Parents: d747e7d
Author: Raphael Ouazana <raphael.ouaz...@linagora.com>
Authored: Fri Jan 27 15:11:11 2017 +0100
Committer: Raphael Ouazana <raphael.ouaz...@linagora.com>
Committed: Fri Jan 27 15:11:11 2017 +0100

----------------------------------------------------------------------
 .../cucumber/GetMessagesMethodStepdefs.java     |  5 +++
 .../test/resources/cucumber/GetMessages.feature | 10 ++++-
 ...mbeddedMultipartWithInlineTextAttachment.eml | 41 ++++++++++++++++++++
 .../jmap/model/MessageContentExtractor.java     | 28 +++++++++----
 .../jmap/model/MessageContentExtractorTest.java | 28 +++++++++++++
 5 files changed, 104 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8e955557/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
index 85c38d8..e6c4c4c 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
@@ -186,6 +186,11 @@ public class GetMessagesMethodStepdefs {
         appendMessage(messageName, "eml/longLine.eml");
     }
 
+    @Given("^the user has a message \"([^\"]*)\" in \"([^\"]*)\" mailbox with 
plain/text inline attachment$")
+    public void appendMessageWithPlainTextInlineAttachment(String messageName, 
String mailbox) throws Throwable {
+        appendMessage(messageName, 
"eml/embeddedMultipartWithInlineTextAttachment.eml");
+    }
+
     private void appendMessage(String messageName, String emlFileName) throws 
Exception {
         ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
         MessageId id = 
mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.lastConnectedUser,

http://git-wip-us.apache.org/repos/asf/james-project/blob/8e955557/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
index d06a81a..9cbd0c1 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
@@ -222,4 +222,12 @@ Feature: GetMessages method
     Given the user has a message "m1" in "inbox" mailbox with two same 
attachments in text
     When the user ask for messages "m1"
     Then no error is returned
-    And the list of attachments of the message contains 2 attachments
\ No newline at end of file
+    And the list of attachments of the message contains 2 attachments
+
+  Scenario: Retrieving message should read content from multipart when some 
inline attachment and both html/text multipart
+    Given the user has a message "m1" in "inbox" mailbox with plain/text 
inline attachment
+    When the user ask for messages "m1"
+    Then no error is returned
+    And the list should contain 1 message
+    And the textBody of the message is "/blabla/\n*bloblo*\n"
+    And the htmlBody of the message is "<i>blabla</i>\n<b>bloblo</b>\n"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/8e955557/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/embeddedMultipartWithInlineTextAttachment.eml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/embeddedMultipartWithInlineTextAttachment.eml
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/embeddedMultipartWithInlineTextAttachment.eml
new file mode 100644
index 0000000..f9c8665
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/embeddedMultipartWithInlineTextAttachment.eml
@@ -0,0 +1,41 @@
+Date: Tue, 03 Jan 2017 16:05:01 +0100
+From: sender <sen...@james.org>
+MIME-Version: 1.0
+To: David DOLCIMASCOLO <david....@linagora.com>
+Subject: Re: [Internet] Rendez-vous
+References: <9b6a4271-69fb-217a-5c14-c68c68375...@linagora.com>
+In-Reply-To: <d5c6f1d6-96e7-8172-9fe6-41fa6c9bd...@linagora.com>
+X-Gie-Attachments: none
+Cc: 
+Content-type: multipart/mixed; boundary="----------=_1483455916-7086-3"
+
+This is a multi-part message in MIME format...
+
+------------=_1483455916-7086-3
+Content-Type: multipart/alternative; 
boundary="------------060506070600060108040700"
+
+This is a multi-part message in MIME format.
+--------------060506070600060108040700
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+/blabla/
+*bloblo*
+
+--------------060506070600060108040700
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+<i>blabla</i>
+<b>bloblo</b>
+
+--------------060506070600060108040700--
+
+------------=_1483455916-7086-3
+Content-Type: text/plain; charset="iso-8859-1"; name="avertissement.txt"
+Content-Disposition: inline; filename="avertissement.txt"
+Content-Transfer-Encoding: binary
+
+inline attachment
+
+------------=_1483455916-7086-3--

http://git-wip-us.apache.org/repos/asf/james-project/blob/8e955557/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
index 626e5fc..721e641 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
@@ -71,7 +71,7 @@ public class MessageContentExtractor {
         case "multipart/alternative":
             return retrieveHtmlAndPlainTextContent(multipart);
         default:
-            return retrieveFirstHtmlOrPlainTextContent(multipart);
+            return retrieveFirstReadablePart(multipart);
         }
     }
 
@@ -95,13 +95,27 @@ public class MessageContentExtractor {
         return new MessageContent(textBody, htmlBody);
     }
 
-    private MessageContent retrieveFirstHtmlOrPlainTextContent(Multipart 
multipart) throws IOException {
-        Optional<String> textBody = Optional.empty();
-        Optional<String> htmlBody = getFirstMatchingTextBody(multipart, 
"text/html");
-        if (! htmlBody.isPresent()) {
-            textBody = getFirstMatchingTextBody(multipart, "text/plain");
+    private MessageContent retrieveFirstReadablePart(Multipart multipart) 
throws IOException {
+        return multipart.getBodyParts()
+            .stream()
+            .filter(this::isNotAttachment)
+            .map(Throwing.function(this::returnIfReadable).sneakyThrow())
+            
.filter(((Predicate<MessageContent>)MessageContent::isEmpty).negate())
+            .findFirst()
+            .orElse(MessageContent.empty());
+    }
+
+    private MessageContent returnIfReadable(Entity entity) throws IOException {
+        if (entity.getMimeType().equals("text/html") && entity.getBody() 
instanceof TextBody) {
+            return 
MessageContent.ofHtmlOnly(asString((TextBody)entity.getBody()));
         }
-        return new MessageContent(textBody, htmlBody);
+        if (entity.getMimeType().equals("text/plain") && entity.getBody() 
instanceof TextBody) {
+            return 
MessageContent.ofTextOnly(asString((TextBody)entity.getBody()));
+        }
+        if (entity.isMultipart() && entity.getBody() instanceof Multipart) {
+            return parseMultipart(entity, (Multipart)entity.getBody());
+        }
+        return MessageContent.empty();
     }
 
     private Optional<String> getFirstMatchingTextBody(Multipart multipart, 
String mimeType) throws IOException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8e955557/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
index c015a3b..0a05e5d 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
@@ -69,6 +69,7 @@ public class MessageContentExtractorTest {
     private BodyPart htmlPart;
     private BodyPart textPart;
     private BodyPart textAttachment;
+    private BodyPart inlineText;
 
     @Before
     public void setup() throws IOException {
@@ -79,6 +80,10 @@ public class MessageContentExtractorTest {
                 .setBody(ATTACHMENT_CONTENT, "plain", Charsets.UTF_8)
                 .setContentDisposition("attachment")
                 .build();
+        inlineText = BodyPartBuilder.create()
+                .setBody(ATTACHMENT_CONTENT, "plain", Charsets.UTF_8)
+                .setContentDisposition("inline")
+                .build();
     }
 
     @Test
@@ -340,4 +345,27 @@ public class MessageContentExtractorTest {
         //Then
         assertThat(actual.getTextBody()).isEmpty();
     }
+
+    @Test
+    public void 
extractShouldRetrieveTextAndHtmlBodyWhenOneInlinedTextAttachmentAndMainContentInMultipart()
 throws IOException {
+        BodyPart multipartAlternative = BodyPartBuilder.create()
+                .setBody(MultipartBuilder.create("alternative")
+                        .addBodyPart(textPart)
+                        .addBodyPart(htmlPart)
+                        .build())
+                .build();
+
+        Multipart multipartMixed = MultipartBuilder.create("mixed")
+                .addBodyPart(multipartAlternative)
+                .addBodyPart(inlineText)
+                .build();
+
+        Message message = MessageBuilder.create()
+                .setBody(multipartMixed)
+                .build();
+
+        MessageContent actual = testee.extract(message);
+        assertThat(actual.getTextBody()).contains(TEXT_CONTENT);
+        assertThat(actual.getHtmlBody()).contains(HTML_CONTENT);
+    }
 }


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

Reply via email to