diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 86e769e6a1f8dc..32327c17f3d249 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -496,7 +496,9 @@ An :class:`SMTP` instance has the following methods: specified in :rfc:`5322`\: *from_addr* is set to the :mailheader:`Sender` field if it is present, and otherwise to the :mailheader:`From` field. *to_addrs* combines the values (if any) of the :mailheader:`To`, - :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one + :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If there's no + *Date* header inside the message, ``send_message`` will add one to the data. + If exactly one set of :mailheader:`Resent-*` headers appear in the message, the regular headers are ignored and the :mailheader:`Resent-*` headers are used instead. If the message contains more than one set of :mailheader:`Resent-*` headers, diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 5e422b704ad4dc..09cfc3c9bdaa85 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -928,6 +928,11 @@ def send_message(self, msg, from_addr=None, to_addrs=None, header_prefix = 'Resent-' else: raise ValueError("message has more than one 'Resent-' header block") + + # RFC 5322 section 3.6, 4th Paragraph + if msg.get('Date', None) is None: + msg['Date'] = email.utils.formatdate() + if from_addr is None: # Prefer the sender field per RFC 2822:3.6.2. from_addr = (msg[header_prefix + 'Sender'] diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 28539f360f5974..93bb5aef16bba2 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -17,6 +17,7 @@ import textwrap import unittest +from unittest.mock import patch from test import support, mock_socket try: @@ -549,6 +550,36 @@ def testSendMessageMultipleResentRaises(self): smtp.send_message(m) smtp.close() + @patch('email.utils.formatdate') + def testSendMessageAddDateIfMissing(self, mocked_date_obj): + current_date = 'Thu, 1 Jan 1970 17:42:00 +0000' + mocked_date_obj.return_value = current_date + m = email.mime.text.MIMEText('A test message') + m['From'] = 'foo@bar.com' + m['To'] = 'John' + m['CC'] = 'Sally, Fred' + m['Bcc'] = 'John Root , "Dinsdale" ' + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) + smtp.send_message(m) + # XXX (see comment in testSend) + time.sleep(0.01) + smtp.quit() + + self.client_evt.set() + self.serv_evt.wait() + self.output.flush() + # The Resent-Bcc headers are deleted before serialization. + del m['Bcc'] + del m['Resent-Bcc'] + # Add the X-Peer header that DebuggingServer adds + m['X-Peer'] = socket.gethostbyname('localhost') + mexpect = '%s%s\n%s' % (MSG_BEGIN, m.as_string(), MSG_END) + self.assertEqual(self.output.getvalue(), mexpect) + debugout = smtpd.DEBUGSTREAM.getvalue() + Date = re.compile(''.join(("\\\\nDate: ", re.escape(current_date))), re.MULTILINE) + self.assertRegex(debugout, Date) + + class NonConnectingTests(unittest.TestCase): def testNotConnected(self): diff --git a/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst b/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst new file mode 100644 index 00000000000000..448d3bcd363d44 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst @@ -0,0 +1,2 @@ +Fix ``smtplib.send_message`` to add Date header if it is missing as per +RFC5322. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy