summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorR David Murray <rdmurray@bitdance.com>2014-08-30 20:51:59 (GMT)
committerR David Murray <rdmurray@bitdance.com>2014-08-30 20:51:59 (GMT)
commit0cff49fcf9b5689a8940c318ea0d846317f3a7d3 (patch)
tree6cfaf2c7f2cd5ae1bec06c6dabab72b23d3e9939
parenta64b92edd3b7c9145e014aac9a15821d7b05b71a (diff)
downloadcpython-0cff49fcf9b5689a8940c318ea0d846317f3a7d3.zip
cpython-0cff49fcf9b5689a8940c318ea0d846317f3a7d3.tar.gz
cpython-0cff49fcf9b5689a8940c318ea0d846317f3a7d3.tar.bz2
#22215: have the smtplib 'quit' command reset the state.
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.
-rwxr-xr-xLib/smtplib.py4
-rw-r--r--Lib/test/test_smtplib.py15
-rw-r--r--Misc/NEWS4
3 files changed, 23 insertions, 0 deletions
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 759b77e..09b4ea6 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -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
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 16e90f4..95a9dbe 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -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()
diff --git a/Misc/NEWS b/Misc/NEWS
index ab5eee6..5111b8a 100644
--- 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.