Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fb59467 authored by cketti's avatar cketti
Browse files

Changed SmtpTransport.writeLine() to only use one OutputStream.write() call....

Changed SmtpTransport.writeLine() to only use one OutputStream.write() call. Apparently some servers got the "be liberal in what you accept from others" part of the robustness principle wrong. When we used multiple calls in writeLine() (command + CR + LF) a separate TCP packet was send each time. It appears that those broken servers accepted the DATA command after DATA + CR and interpreted the LF as part of the actual data. This caused our headers to become part of the body because that LF was interpreted as the empty line that separates headers and body.
As a side effect of this fix sending mail could be slightly faster now due to less packets being sent.

Big thanks to Kevin Newland of Michigan Technological University for organizing a test account.

Fixes issue 799
parent 97c7bf1d
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -414,9 +414,24 @@ public class SmtpTransport extends Transport
        if (K9.DEBUG)
            Log.d(K9.LOG_TAG, "SMTP >>> " + s);

        mOut.write(s.getBytes());
        mOut.write('\r');
        mOut.write('\n');
        /*
         * Note: We can use the string length to compute the buffer size since
         * only ASCII characters are allowed in SMTP commands i.e. this string
         * will never contain multi-byte characters.
         */
        int len = s.length();
        byte[] data = new byte[len + 2];
        s.getBytes(0, len, data, 0);
        data[len+0] = '\r';
        data[len+1] = '\n';

        /*
         * Important: Send command + CRLF using just one write() call. Using
         * multiple calls will likely result in multiple TCP packets and some
         * SMTP servers misbehave if CR and LF arrive in separate pakets.
         * See issue 799.
         */
        mOut.write(data);
        mOut.flush();
    }