Bug 1222046 - Fix SMTP server responding with timeout due to missing CRLF at end of forwarded HTML message. r=mkmelin,jorgk
authorGene Smith <gds@chartertn.net>
Sat, 11 Jan 2020 22:08:33 +0100
changeset 37935 52d792dac3b9f2f4eaa963e6a6c6ee62eb674cb1
parent 37934 d5aa4976ab88940ef8f0fccec5c02f19642b7327
child 37936 56f3244b4b9d73a6da214890b7f08af10c300794
push id398
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:10:28 +0000
reviewersmkmelin, jorgk
bugs1222046
Bug 1222046 - Fix SMTP server responding with timeout due to missing CRLF at end of forwarded HTML message. r=mkmelin,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);