Skip to content

Commit 6d07949

Browse files
author
lafe3402
committed
bpo-28879: add Date header to send_message as per RFC5322
1 parent d37258d commit 6d07949

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

Doc/library/smtplib.rst

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,14 @@ An :class:`SMTP` instance has the following methods:
496496
specified in :rfc:`5322`\: *from_addr* is set to the :mailheader:`Sender`
497497
field if it is present, and otherwise to the :mailheader:`From` field.
498498
*to_addrs* combines the values (if any) of the :mailheader:`To`,
499-
:mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one
500-
set of :mailheader:`Resent-*` headers appear in the message, the regular
501-
headers are ignored and the :mailheader:`Resent-*` headers are used instead.
502-
If the message contains more than one set of :mailheader:`Resent-*` headers,
503-
a :exc:`ValueError` is raised, since there is no way to unambiguously detect
504-
the most recent set of :mailheader:`Resent-` headers.
499+
:mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If there's no
500+
*Date* header inside the message, ``send_message`` will add one to the data.
501+
If exactly one set of :mailheader:`Resent-*` headers appear in the message,
502+
the regular headers are ignored and the :mailheader:`Resent-*` headers are
503+
used instead. If the message contains more than one set of
504+
:mailheader:`Resent-*` headers, a :exc:`ValueError` is raised, since there
505+
is no way to unambiguously detect the most recent set of
506+
:mailheader:`Resent-` headers.
505507

506508
``send_message`` serializes *msg* using
507509
:class:`~email.generator.BytesGenerator` with ``\r\n`` as the *linesep*, and

Lib/smtplib.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,10 @@ def send_message(self, msg, from_addr=None, to_addrs=None,
928928
header_prefix = 'Resent-'
929929
else:
930930
raise ValueError("message has more than one 'Resent-' header block")
931+
932+
# RFC 5322 section 3.6, 4th Paragraph
933+
if msg.get('Date', None) is None:
934+
msg['Date'] = email.utils.formatdate()
931935
if from_addr is None:
932936
# Prefer the sender field per RFC 2822:3.6.2.
933937
from_addr = (msg[header_prefix + 'Sender']

Lib/test/test_smtplib.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import unittest
2121
from test import support, mock_socket
2222
from test.support import HOST, HOSTv4, HOSTv6
23+
from unittest.mock import patch
2324

2425

2526
if sys.platform == 'darwin':
@@ -558,6 +559,38 @@ def testSendMessageMultipleResentRaises(self):
558559
smtp.send_message(m)
559560
smtp.close()
560561

562+
@patch('email.utils.formatdate')
563+
def testSendMessageAddDateIfMissing(self, mocked_date_obj):
564+
current_date = 'Thu, 1 Jan 1970 17:42:00 +0000'
565+
566+
mocked_date_obj.return_value = current_date
567+
m = email.mime.text.MIMEText('A test message')
568+
m['From'] = 'foo@bar.com'
569+
m['To'] = 'John'
570+
m['CC'] = 'Sally, Fred'
571+
m['Bcc'] = 'John Root <root@localhost>, "Dinsdale" <warped@silly.walks.com>'
572+
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
573+
smtp.send_message(m)
574+
# XXX (see comment in testSend)
575+
time.sleep(0.01)
576+
smtp.quit()
577+
578+
self.client_evt.set()
579+
self.serv_evt.wait()
580+
self.output.flush()
581+
# The Resent-Bcc headers are deleted before serialization.
582+
del m['Bcc']
583+
del m['Resent-Bcc']
584+
# Remove the X-Peer header that DebuggingServer adds.
585+
test_output = self.get_output_without_xpeer()
586+
mexpect = '%s%s\n%s' % (MSG_BEGIN, m.as_string(), MSG_END)
587+
self.assertEqual(test_output, mexpect)
588+
debugout = smtpd.DEBUGSTREAM.getvalue()
589+
Date = re.compile(''.join(("\\\\nDate: ", re.escape(current_date))), re.MULTILINE)
590+
self.assertRegex(debugout, Date)
591+
592+
593+
561594
class NonConnectingTests(unittest.TestCase):
562595

563596
def testNotConnected(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix ``smtplib.send_message`` to add a ``Date`` header if it is missing as per
2+
RFC5322.

0 commit comments

Comments
 (0)