Repository: james-project Updated Branches: refs/heads/master 2bfe6ce59 -> a8fe12f52
JAMES-1828 Ignore attachments in text parts Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a8fe12f5 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a8fe12f5 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a8fe12f5 Branch: refs/heads/master Commit: a8fe12f52e55b6eb233aa01df21e2451c1a2655c Parents: 71ceb33 Author: Raphael Ouazana <raphael.ouaz...@linagora.com> Authored: Fri Sep 23 11:10:51 2016 +0200 Committer: Raphael Ouazana <raphael.ouaz...@linagora.com> Committed: Tue Sep 27 10:06:51 2016 +0200 ---------------------------------------------------------------------- .../integration/SetMessagesMethodTest.java | 62 ++++++++++++++++++++ .../jmap/model/MessageContentExtractor.java | 27 +++------ .../jmap/model/MessageContentExtractorTest.java | 26 +++++++- 3 files changed, 94 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/a8fe12f5/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java index 58e2609..fe5f5c2 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java @@ -2265,4 +2265,66 @@ public abstract class SetMessagesMethodTest { .body(firstAttachment + ".type", equalTo("text/html")) .body(firstAttachment + ".size", equalTo((int) attachment.getSize())); } + @Test + public void attachmentAndEmptyBodyShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithTextAttachmentWithoutMailBody() throws Exception { + jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "sent"); + + Attachment attachment = Attachment.builder() + .bytes(("some text").getBytes(Charsets.UTF_8)) + .type("text/plain; charset=UTF-8") + .build(); + uploadTextAttachment(attachment); + + String messageCreationId = "creationId"; + String fromAddress = username; + String outboxId = getOutboxId(accessToken); + String requestBody = "[" + + " [" + + " \"setMessages\","+ + " {" + + " \"create\": { \"" + messageCreationId + "\" : {" + + " \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," + + " \"to\": [{ \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}]," + + " \"subject\": \"Message with an attachment\"," + + " \"mailboxIds\": [\"" + outboxId + "\"], " + + " \"attachments\": [" + + " {\"blobId\" : \"" + attachment.getAttachmentId().getId() + "\", " + + " \"type\" : \"" + attachment.getType() + "\", " + + " \"size\" : " + attachment.getSize() + ", " + + " \"isInline\" : false }" + + " ]" + + " }}" + + " }," + + " \"#0\"" + + " ]" + + "]"; + + given() + .header("Authorization", accessToken.serialize()) + .body(requestBody) + .when() + .post("/jmap"); + + calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken)); + + String firstMessage = ARGUMENTS + ".list[0]"; + String firstAttachment = firstMessage + ".attachments[0]"; + String presumedMessageId = "usern...@domain.tld|INBOX|1"; + given() + .header("Authorization", accessToken.serialize()) + .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + "\"]}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .statusCode(200) + .log().ifValidationFails() + .body(NAME, equalTo("messages")) + .body(ARGUMENTS + ".list", hasSize(1)) + .body(firstMessage + ".textBody", isEmptyOrNullString()) + .body(firstMessage + ".htmlBody", isEmptyOrNullString()) + .body(firstMessage + ".attachments", hasSize(1)) + .body(firstAttachment + ".blobId", equalTo(attachment.getAttachmentId().getId())) + .body(firstAttachment + ".type", equalTo("text/plain")) + .body(firstAttachment + ".size", equalTo((int) attachment.getSize())); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/a8fe12f5/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 035766b..384b8a5 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 @@ -20,7 +20,6 @@ package org.apache.james.jmap.model; import java.io.IOException; -import java.util.List; import java.util.Objects; import java.util.Optional; @@ -65,11 +64,9 @@ public class MessageContentExtractor { private MessageContent parseMultipartContent(Entity entity, Multipart multipart) throws IOException { switch(entity.getMimeType()) { case "multipart/alternative": - return parseMultipartAlternative(multipart); - case "multipart/related": - return parseMultipartRelated(multipart); + return retrieveHtmlAndPlainTextContent(multipart); default: - return parseMultipartMixed(multipart); + return retrieveFirstHtmlOrPlainTextContent(multipart); } } @@ -87,24 +84,13 @@ public class MessageContentExtractor { return IOUtils.toString(textBody.getInputStream(), textBody.getMimeCharset()); } - private MessageContent parseMultipartMixed(Multipart multipart) throws IOException { - List<Entity> parts = multipart.getBodyParts(); - if (! parts.isEmpty()) { - Entity firstPart = parts.get(0); - if (firstPart.getBody() instanceof TextBody) { - return parseTextBody(firstPart, (TextBody)firstPart.getBody()); - } - } - return MessageContent.empty(); - } - - private MessageContent parseMultipartAlternative(Multipart multipart) throws IOException { + private MessageContent retrieveHtmlAndPlainTextContent(Multipart multipart) throws IOException { Optional<String> textBody = getFirstMatchingTextBody(multipart, "text/plain"); Optional<String> htmlBody = getFirstMatchingTextBody(multipart, "text/html"); return new MessageContent(textBody, htmlBody); } - private MessageContent parseMultipartRelated(Multipart multipart) throws IOException { + private MessageContent retrieveFirstHtmlOrPlainTextContent(Multipart multipart) throws IOException { Optional<String> textBody = Optional.empty(); Optional<String> htmlBody = getFirstMatchingTextBody(multipart, "text/html"); if (! htmlBody.isPresent()) { @@ -117,6 +103,7 @@ public class MessageContentExtractor { return multipart.getBodyParts() .stream() .filter(part -> mimeType.equals(part.getMimeType())) + .filter(this::isNotAttachment) .map(Entity::getBody) .filter(TextBody.class::isInstance) .map(TextBody.class::cast) @@ -124,6 +111,10 @@ public class MessageContentExtractor { .map(Throwing.function(this::asString).sneakyThrow()); } + private boolean isNotAttachment(Entity part) { + return part.getDispositionType() == null; + } + public static class MessageContent { private final Optional<String> textBody; private final Optional<String> htmlBody; http://git-wip-us.apache.org/repos/asf/james-project/blob/a8fe12f5/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 ba2f486..d6eb03c 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 @@ -39,17 +39,23 @@ public class MessageContentExtractorTest { private static final String BINARY_CONTENT = "binary"; private static final String TEXT_CONTENT = "text content"; private static final String HTML_CONTENT = "<b>html</b> content"; + private static final String ATTACHMENT_CONTENT = "attachment content"; private MessageContentExtractor testee; private BodyPart htmlPart; private BodyPart textPart; + private BodyPart textAttachment; @Before public void setup() throws IOException { testee = new MessageContentExtractor(); textPart = BodyPartBuilder.create().setBody(TEXT_CONTENT, "plain", Charsets.UTF_8).build(); htmlPart = BodyPartBuilder.create().setBody(HTML_CONTENT, "html", Charsets.UTF_8).build(); + textAttachment = BodyPartBuilder.create() + .setBody(ATTACHMENT_CONTENT, "plain", Charsets.UTF_8) + .setContentDisposition("attachment") + .build(); } @Test @@ -123,16 +129,30 @@ public class MessageContentExtractorTest { } @Test - public void extractShouldReturnFirstPartOnlyWhenMultipartMixedAndFirstPartIsText() throws IOException { + public void extractShouldReturnFirstNonAttachmentPartWhenMultipartMixed() throws IOException { Multipart multipart = MultipartBuilder.create("mixed") - .addBodyPart(textPart) + .addBodyPart(textAttachment) .addBodyPart(htmlPart) + .addBodyPart(textPart) .build(); Message message = MessageBuilder.create() .setBody(multipart) .build(); MessageContent actual = testee.extract(message); - assertThat(actual.getTextBody()).contains(TEXT_CONTENT); + assertThat(actual.getHtmlBody()).contains(HTML_CONTENT); + assertThat(actual.getTextBody()).isEmpty(); + } + + @Test + public void extractShouldReturnEmptyWhenMultipartMixedAndFirstPartIsATextAttachment() throws IOException { + Multipart multipart = MultipartBuilder.create("mixed") + .addBodyPart(textAttachment) + .build(); + Message message = MessageBuilder.create() + .setBody(multipart) + .build(); + MessageContent actual = testee.extract(message); + assertThat(actual.getTextBody()).isEmpty(); assertThat(actual.getHtmlBody()).isEmpty(); } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org