Loading django/core/mail/message.py +8 −1 Original line number Diff line number Diff line Loading @@ -25,11 +25,15 @@ from django.utils.encoding import force_text # some spam filters. utf8_charset = Charset.Charset('utf-8') utf8_charset.body_encoding = None # Python defaults to BASE64 utf8_charset_qp = Charset.Charset('utf-8') utf8_charset_qp.body_encoding = Charset.QP # Default MIME type to use on attachments (if it is not explicitly given # and cannot be guessed). DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' RFC5322_EMAIL_LINE_LENGTH_LIMIT = 998 class BadHeaderError(ValueError): pass Loading Loading @@ -169,7 +173,10 @@ class SafeMIMEText(MIMEMixin, MIMEText): # We do it manually and trigger re-encoding of the payload. MIMEText.__init__(self, _text, _subtype, None) del self['Content-Transfer-Encoding'] self.set_payload(_text, utf8_charset) has_long_lines = any(len(l) > RFC5322_EMAIL_LINE_LENGTH_LIMIT for l in _text.splitlines()) # Quoted-Printable encoding has the side effect of shortening long # lines, if any (#22561). self.set_payload(_text, utf8_charset_qp if has_long_lines else utf8_charset) self.replace_header('Content-Type', 'text/%s; charset="%s"' % (_subtype, _charset)) elif _charset is None: # the default value of '_charset' is 'us-ascii' on Python 2 Loading tests/mail/tests.py +16 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,22 @@ class BaseEmailBackendTests(HeadersCheckMixin, object): self.assertEqual(message["subject"], '=?utf-8?q?Ch=C3=A8re_maman?=') self.assertEqual(force_text(message.get_payload(decode=True)), 'Je t\'aime très fort') def test_send_long_lines(self): """ Email line length is limited to 998 chars by the RFC: https://tools.ietf.org/html/rfc5322#section-2.1.1 Message body containing longer lines are converted to Quoted-Printable to avoid having to insert newlines, which could be hairy to do properly. """ email = EmailMessage('Subject', "Comment ça va? " * 100, 'from@example.com', ['to@example.com']) email.send() message = self.get_the_message() self.assertMessageHasHeaders(message, { ('MIME-Version', '1.0'), ('Content-Type', 'text/plain; charset="utf-8"'), ('Content-Transfer-Encoding', 'quoted-printable'), }) def test_send_many(self): email1 = EmailMessage('Subject', 'Content1', 'from@example.com', ['to@example.com']) email2 = EmailMessage('Subject', 'Content2', 'from@example.com', ['to@example.com']) Loading Loading
django/core/mail/message.py +8 −1 Original line number Diff line number Diff line Loading @@ -25,11 +25,15 @@ from django.utils.encoding import force_text # some spam filters. utf8_charset = Charset.Charset('utf-8') utf8_charset.body_encoding = None # Python defaults to BASE64 utf8_charset_qp = Charset.Charset('utf-8') utf8_charset_qp.body_encoding = Charset.QP # Default MIME type to use on attachments (if it is not explicitly given # and cannot be guessed). DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' RFC5322_EMAIL_LINE_LENGTH_LIMIT = 998 class BadHeaderError(ValueError): pass Loading Loading @@ -169,7 +173,10 @@ class SafeMIMEText(MIMEMixin, MIMEText): # We do it manually and trigger re-encoding of the payload. MIMEText.__init__(self, _text, _subtype, None) del self['Content-Transfer-Encoding'] self.set_payload(_text, utf8_charset) has_long_lines = any(len(l) > RFC5322_EMAIL_LINE_LENGTH_LIMIT for l in _text.splitlines()) # Quoted-Printable encoding has the side effect of shortening long # lines, if any (#22561). self.set_payload(_text, utf8_charset_qp if has_long_lines else utf8_charset) self.replace_header('Content-Type', 'text/%s; charset="%s"' % (_subtype, _charset)) elif _charset is None: # the default value of '_charset' is 'us-ascii' on Python 2 Loading
tests/mail/tests.py +16 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,22 @@ class BaseEmailBackendTests(HeadersCheckMixin, object): self.assertEqual(message["subject"], '=?utf-8?q?Ch=C3=A8re_maman?=') self.assertEqual(force_text(message.get_payload(decode=True)), 'Je t\'aime très fort') def test_send_long_lines(self): """ Email line length is limited to 998 chars by the RFC: https://tools.ietf.org/html/rfc5322#section-2.1.1 Message body containing longer lines are converted to Quoted-Printable to avoid having to insert newlines, which could be hairy to do properly. """ email = EmailMessage('Subject', "Comment ça va? " * 100, 'from@example.com', ['to@example.com']) email.send() message = self.get_the_message() self.assertMessageHasHeaders(message, { ('MIME-Version', '1.0'), ('Content-Type', 'text/plain; charset="utf-8"'), ('Content-Transfer-Encoding', 'quoted-printable'), }) def test_send_many(self): email1 = EmailMessage('Subject', 'Content1', 'from@example.com', ['to@example.com']) email2 = EmailMessage('Subject', 'Content2', 'from@example.com', ['to@example.com']) Loading