diff -r 0b78a8c35357 Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst Thu Dec 15 18:58:35 2016 -0500 +++ b/Doc/library/smtplib.rst Sun Dec 18 21:47:08 2016 -0500 @@ -496,7 +496,7 @@ 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 a 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 -r 0b78a8c35357 Lib/smtplib.py --- a/Lib/smtplib.py Thu Dec 15 18:58:35 2016 -0500 +++ b/Lib/smtplib.py Sun Dec 18 21:47:08 2016 -0500 @@ -912,21 +912,20 @@ # 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822 # Section 3.6.6). In such a case, we use the 'Resent-*' fields. However, # if there is more than one 'Resent-' block there's no way to - # unambiguously determine which one is the most recent in all cases, - # so rather than guess we raise a ValueError in that case. - # - # TODO implement heuristics to guess the correct Resent-* block with an - # option allowing the user to enable the heuristics. (It should be - # possible to guess correctly almost all of the time.) + # unambiguously determine which one is the most recent in all cases. + # See RFC 5322 section 3.6.6, first paragraph for more details about the + # "should" that the code should respect. - self.ehlo_or_helo_if_needed() - resent = msg.get_all('Resent-Date') - if resent is None: - header_prefix = '' - elif len(resent) == 1: - header_prefix = 'Resent-' - else: + if [ header[0] for header in msg._headers ].count('Resent-Date') > 1: raise ValueError("message has more than one 'Resent-' header block") + + #Resent or original? + header_prefix = 'Resent-' if len(msg.get('Resent-Date','')) >= 1 else '' + + # 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'] @@ -1110,5 +1109,6 @@ server = SMTP('localhost') server.set_debuglevel(1) - server.sendmail(fromaddr, toaddrs, msg) + #server.sendmail(fromaddr, toaddrs, msg) + server.send_message(from_addr=fromaddr, to_addrs=toaddrs, msg=email.message_from_string(msg)) server.quit() diff -r 0b78a8c35357 Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py Thu Dec 15 18:58:35 2016 -0500 +++ b/Lib/test/test_smtplib.py Sun Dec 18 21:47:08 2016 -0500 @@ -531,22 +531,38 @@ re.MULTILINE) self.assertRegex(debugout, to_addr) - def testSendMessageMultipleResentRaises(self): + def testSendMessageMultipleResent(self): + first_date = 'Thu, 1 Jan 1970 17:42:00 +0000' + first_from = 'holy@grail.net' + first_to = 'Martha , Jeff' 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" ' - m['Resent-Date'] = 'Thu, 1 Jan 1970 17:42:00 +0000' - m['Resent-From'] = 'holy@grail.net' - m['Resent-To'] = 'Martha , Jeff' m['Resent-Bcc'] = 'doe@losthope.net' m['Resent-Date'] = 'Thu, 2 Jan 1970 17:42:00 +0000' m['Resent-To'] = 'holy@grail.net' m['Resent-From'] = 'Martha , Jeff' + m._headers.insert(0,m.policy.header_store_parse('Resent-Date', first_date)) + m._headers.insert(0,m.policy.header_store_parse('Resent-From', first_from)) + m._headers.insert(0,m.policy.header_store_parse('Resent-To', first_to)) + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) with self.assertRaises(ValueError): - smtp.send_message(m) + smtp.send_message(m) #Raise an error at the moment + self.assertEqual(first=m.get('Resent-Date'), + second=first_date, + msg=""" + The Resent-Date order is not read correctly or + something wrong happened. + """) + self.assertEqual(first=m.get('Resent-From'), + second=first_from, + msg=""" + The Resent-From order is not read correctly or + something wrong happened. + """) smtp.close() class NonConnectingTests(unittest.TestCase):