Bug 1222046 - Fix SMTP server responding with timeout due to missing CRLF at end of forwarded HTML message. r=mkmelin,jorgk a=jorgk
authorGene Smith <gds@chartertn.net>
Sat, 11 Jan 2020 22:08:33 +0100
changeset 36991 1dcefcd94db905a5374efb3b7851fe3623436be4
parent 36990 4c6fc6e8bee93f83b0f1e5347b81b00c47916077
child 36992 8efbc97ee1181794e7292ff7b7702698c306af50
push id2545
push usergeoff@darktrojan.net
push dateWed, 15 Jan 2020 21:10:47 +0000
treeherdercomm-beta@d7e99ea4d5ce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, jorgk, jorgk
bugs1222046
Bug 1222046 - Fix SMTP server responding with timeout due to missing CRLF at end of forwarded HTML message. r=mkmelin,jorgk a=jorgk
mailnews/compose/src/nsMsgCompose.cpp
mailnews/compose/test/unit/test_longLines.js
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -1259,16 +1259,19 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
       flags |= nsIDocumentEncoder::OutputPersistNBSP;
     }
     rv = m_editor->OutputToString(contentType, flags, msgBody);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     m_compFields->GetBody(msgBody);
   }
   if (!msgBody.IsEmpty()) {
+    // Ensure body ends in CRLF to avoid SMTP server timeout when sent.
+    if (!StringEndsWith(msgBody, NS_LITERAL_STRING("\r\n")))
+      msgBody.AppendLiteral("\r\n");
     bool isAsciiOnly = mozilla::IsAsciiNullTerminated(
         static_cast<const char16_t *>(msgBody.get()));
     // Convert body to mail charset
     nsCString outCString;
     rv = nsMsgI18NConvertFromUnicode(
         charset ? nsDependentCString(charset) : EmptyCString(), msgBody,
         outCString, true);
     if (m_compFields->GetForceMsgEncoding()) isAsciiOnly = false;
--- a/mailnews/compose/test/unit/test_longLines.js
+++ b/mailnews/compose/test/unit/test_longLines.js
@@ -122,17 +122,18 @@ async function testBodyWithLongLine() {
   fields.to = "Nobody <nobody@tinderbox.invalid>";
   fields.subject = "Message with 1200 byte line in body";
   fields.characterSet = "UTF-8";
   let htmlMessage =
     "<html><head>" +
     '<meta http-equiv="content-type" content="text/html; charset=utf-8">' +
     "</head><body>" +
     longMultibyteLine +
-    "</body></html>";
+    "</body></html>" +
+    newline;
   fields.body = htmlMessage;
   await richCreateMessage(fields, [], identity);
   checkDraftHeadersAndBody(
     {
       "Content-Type": "text/html; charset=UTF-8",
       "Content-Transfer-Encoding": "base64",
     },
     htmlMessage
@@ -143,17 +144,17 @@ async function testBodyWithLongLine() {
   fields.forcePlainText = true;
   fields.useMultipartAlternative = false;
   await richCreateMessage(fields, [], identity);
   checkDraftHeadersAndBody(
     {
       "Content-Type": "text/plain; charset=UTF-8; format=flowed",
       "Content-Transfer-Encoding": "base64",
     },
-    longMultibyteLine + newline // Expected body: The message without the tags.
+    longMultibyteLine + " " + newline + newline // Expected body: The message without the tags.
   );
 
   // Now CJK.
   fields.forcePlainText = false;
   htmlMessage =
     "<html><head>" +
     '<meta http-equiv="content-type" content="text/html; charset=utf-8">' +
     "</head><body>" +
@@ -161,30 +162,30 @@ async function testBodyWithLongLine() {
     "</body></html>";
   fields.body = htmlMessage;
   await richCreateMessage(fields, [], identity);
   checkDraftHeadersAndBody(
     {
       "Content-Type": "text/html; charset=UTF-8",
       "Content-Transfer-Encoding": "base64",
     },
-    htmlMessage
+    htmlMessage + newline
   );
 
   // Again, but this time as plain text.
   fields.body = htmlMessage;
   fields.forcePlainText = true;
   fields.useMultipartAlternative = false;
   await richCreateMessage(fields, [], identity);
   checkDraftHeadersAndBody(
     {
       "Content-Type": "text/plain; charset=UTF-8; format=flowed",
       "Content-Transfer-Encoding": "base64",
     },
-    longMultibyteLineCJK + newline // Expected body: The message without the tags.
+    longMultibyteLineCJK + " " + newline + newline // Expected body: The message without the tags.
   );
 
   // Now a special test for ISO-2022-JP.
   fields.characterSet = "ISO-2022-JP";
 
   fields.forcePlainText = false;
   htmlMessage =
     "<html><head>" +
@@ -194,17 +195,17 @@ async function testBodyWithLongLine() {
     "</body></html>";
   fields.body = htmlMessage;
   await richCreateMessage(fields, [], identity);
   checkDraftHeadersAndBody(
     {
       "Content-Type": "text/html; charset=ISO-2022-JP",
       "Content-Transfer-Encoding": "base64",
     },
-    htmlMessage,
+    htmlMessage + newline,
     "ISO-2022-JP"
   );
 
   // Again, but this time as plain text.
   fields.body = htmlMessage;
   fields.forcePlainText = true;
   fields.useMultipartAlternative = false;
   await richCreateMessage(fields, [], identity);