SmtpClient.DataAsync Adds Extra CRLF
See original GitHub issueSmtpClient currently adds an extra CRLF when sending messages to email servers.
Because of this bug, the delivered message contains an extra CRLF compared to the actual message when you do MimeMessage.WriteToAsync.
As per the RFC:
The mail data are terminated by a line containing only a period, that is, the character sequence “<CRLF>.<CRLF>”, where the first <CRLF> is actually the terminator of the previous line (see Section 4.5.2). This is the end of mail data indication. The first <CRLF> of this terminating sequence is also the <CRLF> that ends the final line of the data (message text) or, if there was no mail data, ends the DATA command itself (the “no mail data” case does not conform to this specification since it would require that neither the trace header fields required by this specification nor the message header section required by RFC 5322 [4] be transmitted). https://tools.ietf.org/html/rfc5321#section-4.1.1.4
The EndData parameter in SmtpClient.cs (https://github.com/jstedfast/MailKit/blob/master/MailKit/Net/Smtp/SmtpClient.cs#L77) is currently:
static readonly byte[] EndData = Encoding.ASCII.GetBytes ("\r\n.\r\n");
It should be:
static readonly byte[] EndData = Encoding.ASCII.GetBytes (".\r\n");
The first CLRF should be from the end of the message itself.
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (8 by maintainers)
Yea, the EnsureNewLine thing on FormatOptions was added later and I didn’t update the SmtpClient logic. Not sure if I just forgot or if I just wasn’t 100% confident at the time that there weren’t any corner cases where it didn’t work.
Pretty sure it’s a solved problem when you write to a Dos2UnixFilter or a Unix2DosFilter because the Flush() logic tracks what the last character written was. and makes sure to write a new-line sequence when flushed if it hasn’t already ended with one.
I can probably remove it from SmtpClient, but I need time to verify that it won’t break anything.
Correct. No need to track CRLF vs LF in the SmtpDataFilter because all content that reaches the SmtpDataFilter has already been converted to CRLF from LF.