]> granicus.if.org Git - python/commitdiff
#22215: have the smtplib 'quit' command reset the state.
authorR David Murray <rdmurray@bitdance.com>
Sat, 30 Aug 2014 20:51:59 +0000 (16:51 -0400)
committerR David Murray <rdmurray@bitdance.com>
Sat, 30 Aug 2014 20:51:59 +0000 (16:51 -0400)
Without this reset, starttls would fail if a connect/starttls was done after a
quit, because smtplib assumed the existing value of emspt_features was
accurate, but it gets reset when starttls completes (and the new value does
not contain the starttls capability, since tls is already started at that
point).  (There may be additional places where this lack of reset was an
issue as well.)

Patch by Milan Oberkirch.

Lib/smtplib.py
Lib/test/test_smtplib.py
Misc/NEWS

index 759b77e47fa3e6d2abe13c8407ec5e877e2b9373..09b4ea647962a7797a4ffd0097bf3f1079d9f286 100755 (executable)
@@ -866,6 +866,10 @@ class SMTP:
     def quit(self):
         """Terminate the SMTP session."""
         res = self.docmd("quit")
+        # A new EHLO is required after reconnecting with connect()
+        self.ehlo_resp = self.helo_resp = None
+        self.esmtp_features = {}
+        self.does_esmtp = False
         self.close()
         return res
 
index 16e90f4ab321ec6afcfaf8ff215d7cf46b0471c8..95a9dbe91225e05df364114f05b4fb686554850e 100644 (file)
@@ -858,6 +858,21 @@ class SMTPSimTests(unittest.TestCase):
             self.assertIn(sim_auth_login_password, str(err))
         smtp.close()
 
+    def test_quit_resets_greeting(self):
+        smtp = smtplib.SMTP(HOST, self.port,
+                            local_hostname='localhost',
+                            timeout=15)
+        code, message = smtp.ehlo()
+        self.assertEqual(code, 250)
+        self.assertIn('size', smtp.esmtp_features)
+        smtp.quit()
+        self.assertNotIn('size', smtp.esmtp_features)
+        smtp.connect(HOST, self.port)
+        self.assertNotIn('size', smtp.esmtp_features)
+        smtp.ehlo_or_helo_if_needed()
+        self.assertIn('size', smtp.esmtp_features)
+        smtp.quit()
+
     def test_with_statement(self):
         with smtplib.SMTP(HOST, self.port) as smtp:
             code, message = smtp.noop()
index ab5eee6bb903a617d9635370dae35428fd8b85d3..5111b8aa16004bd388f369cd74648ada535b7b1c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #22216: smtplib now resets its state more completely after a quit.  The
+  most obvious consequence of the previous behavior was a STARTTLS failure
+  during a connect/starttls/quit/connect/starttls sequence.
+
 - Issue #22185: Fix an occasional RuntimeError in threading.Condition.wait()
   caused by mutation of the waiters queue without holding the lock.  Patch
   by Doug Zongker.