You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/10/19 01:25:15 UTC
[james-project] branch master updated: JAMES-3369 Fallback to
text/plain when no HTML in multipart/alternative (#698)
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
The following commit(s) were added to refs/heads/master by this push:
new 8b0285c JAMES-3369 Fallback to text/plain when no HTML in multipart/alternative (#698)
8b0285c is described below
commit 8b0285c51f56e0f155150ba750cb219a3f4a335a
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Tue Oct 19 08:25:10 2021 +0700
JAMES-3369 Fallback to text/plain when no HTML in multipart/alternative (#698)
---
.../src/main/resources/eml/alternative.cal.eml | 55 ++++++++++++++++++++
.../rfc8621/contract/EmailGetMethodContract.scala | 59 ++++++++++++++++++++++
.../org/apache/james/jmap/mail/EmailBodyPart.scala | 6 ++-
3 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/alternative.cal.eml b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/alternative.cal.eml
new file mode 100644
index 0000000..2ec5d9d
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/alternative.cal.eml
@@ -0,0 +1,55 @@
+Return-Path: <j...@linagora.com>
+MIME-version: 1.0
+X-LINAGORA-Copy-Delivery-Done: 1
+From: J <j...@linagora.com>
+Message-ID: <00...@linagora.com>
+To: B <b...@linagora.com>
+Date: Thu, 14 Oct 2021 16:04:30 +0200
+Subject: A little explanation
+Content-type: multipart/mixed; boundary="Boundary_(ID_qyG4ZdjoAsiZ+Jo19dCbWQ)"
+
+
+--Boundary_(ID_qyG4ZdjoAsiZ+Jo19dCbWQ)
+Content-type: multipart/alternative;
+ boundary="Boundary_(ID_ryU4ZdJoASiZ+Jo21dCbwA)"
+
+
+--Boundary_(ID_ryU4ZdJoASiZ+Jo21dCbwA)
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8BIT
+
+J <j...@linagora.com> a accepté votre invitation.
+--Boundary_(ID_ryU4ZdJoASiZ+Jo21dCbwA)
+Content-type: text/calendar; method=REPLY; charset=UTF-8
+Content-transfer-encoding: 8BIT
+
+BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VTIMEZONE
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:08985ae5-8e62-4f3e-971d-27c8b40cf838
+END:VEVENT
+END:VCALENDAR
+
+
+--Boundary_(ID_ryU4ZdJoASiZ+Jo21dCbwA)--
+
+--Boundary_(ID_qyG4ZdjoAsiZ+Jo19dCbWQ)
+Content-type: application/ics; name=invite.ics
+Content-transfer-encoding: 8BIT
+Content-disposition: attachment; filename=invite.ics
+
+BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VTIMEZONE
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:08985ae5-8e62-4f3e-971d-27c8b40cf838
+END:VEVENT
+END:VCALENDAR
+
+
+--Boundary_(ID_qyG4ZdjoAsiZ+Jo19dCbWQ)--
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
index 47e9254..694955d 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
@@ -4539,6 +4539,65 @@ trait EmailGetMethodContract {
}
@Test
+ def htmlBodyValuesShouldFallBackToPlainTextWhenNoHtmlPart(server: GuiceJamesServer): Unit = {
+ val path = MailboxPath.inbox(BOB)
+ server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+ val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, path, AppendCommand.from(
+ ClassLoaderUtils.getSystemResourceAsSharedStream("eml/alternative.cal.eml")))
+ .getMessageId
+
+ val request =
+ s"""{
+ | "using": [
+ | "urn:ietf:params:jmap:core",
+ | "urn:ietf:params:jmap:mail"],
+ | "methodCalls": [[
+ | "Email/get",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "ids": ["${messageId.serialize}"],
+ | "properties":["bodyValues", "htmlBody"],
+ | "fetchHTMLBodyValues": true
+ | },
+ | "c1"]]
+ |}""".stripMargin
+ val response = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response)
+ .whenIgnoringPaths("methodResponses[0][1].state")
+ .inPath(s"methodResponses[0][1].list[0]")
+ .isEqualTo(
+ s"""{
+ | "htmlBody": [{
+ | "charset": "UTF-8",
+ | "size": 47,
+ | "partId": "3",
+ | "blobId": "${messageId.serialize()}_3",
+ | "type": "text/plain"
+ | }],
+ | "id": "${messageId.serialize()}",
+ | "bodyValues": {
+ | "3": {
+ | "value": "J <j...@linagora.com> a accepté votre invitation.",
+ | "isEncodingProblem": false,
+ | "isTruncated": false
+ | }
+ | }
+ |}""".stripMargin)
+ }
+
+ @Test
def textAndHtmlBodyValuesForComplexMultipart(server: GuiceJamesServer): Unit = {
val path = MailboxPath.inbox(BOB)
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailBodyPart.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailBodyPart.scala
index dc2646d..6d6d75c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailBodyPart.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailBodyPart.scala
@@ -283,8 +283,10 @@ case class EmailBodyPart(partId: PartId,
}
private def htmlBodyOfMultipart: List[EmailBodyPart] = `type` match {
- case MULTIPART_ALTERNATIVE => getBodyParts(subParts.getOrElse(Nil), TEXT_HTML)
- .flatMap(subPart => subPart.htmlBody)
+ case MULTIPART_ALTERNATIVE => Some(getBodyParts(subParts.getOrElse(Nil), TEXT_HTML)
+ .flatMap(subPart => subPart.htmlBody))
+ .filter(_.nonEmpty)
+ .getOrElse(textBodyOfMultipart)
case _ => subParts.getOrElse(Nil)
.flatMap(subPart => subPart.htmlBody)
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org