Skip to content

Commit f0bb986

Browse files
committed
gh-48392: Fix smtplib.SMTP.close() not resetting the EHLO state
Move the reset from quit() into close(), which quit() and the disconnect paths all call.
1 parent fc083ad commit f0bb986

3 files changed

Lines changed: 42 additions & 4 deletions

File tree

‎Lib/smtplib.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,11 @@ def send_message(self, msg, from_addr=None, to_addrs=None,
989989

990990
def close(self):
991991
"""Close the connection to the SMTP server."""
992+
# A new EHLO is required after reconnecting with connect()
993+
self.ehlo_resp = self.helo_resp = None
994+
self.esmtp_features = {}
995+
self.does_esmtp = False
996+
992997
try:
993998
file = self.file
994999
self.file = None
@@ -1003,10 +1008,6 @@ def close(self):
10031008
def quit(self):
10041009
"""Terminate the SMTP session."""
10051010
res = self.docmd("quit")
1006-
# A new EHLO is required after reconnecting with connect()
1007-
self.ehlo_resp = self.helo_resp = None
1008-
self.esmtp_features = {}
1009-
self.does_esmtp = False
10101011
self.close()
10111012
return res
10121013

‎Lib/test/test_smtplib.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,40 @@ def test_quit_resets_greeting(self):
12651265
self.assertIn('size', smtp.esmtp_features)
12661266
smtp.quit()
12671267

1268+
def test_close_resets_greeting(self):
1269+
smtp = smtplib.SMTP(HOST, self.port,
1270+
local_hostname='localhost',
1271+
timeout=support.LOOPBACK_TIMEOUT)
1272+
code, _ = smtp.ehlo()
1273+
self.assertEqual(code, 250)
1274+
self.assertIn('size', smtp.esmtp_features)
1275+
smtp.close()
1276+
self.assertNotIn('size', smtp.esmtp_features)
1277+
smtp.connect(HOST, self.port)
1278+
self.assertNotIn('size', smtp.esmtp_features)
1279+
smtp.ehlo_or_helo_if_needed()
1280+
self.assertIn('size', smtp.esmtp_features)
1281+
smtp.quit()
1282+
1283+
def test_with_statement_resets_greeting(self):
1284+
with smtplib.SMTP(HOST, self.port,
1285+
local_hostname='localhost',
1286+
timeout=support.LOOPBACK_TIMEOUT) as smtp:
1287+
smtp.ehlo()
1288+
self.assertIn('size', smtp.esmtp_features)
1289+
1290+
self.assertNotIn('size', smtp.esmtp_features)
1291+
1292+
msg = EmailMessage()
1293+
msg['From'] = 'test_from'
1294+
msg['To'] = 'test_to'
1295+
msg['Subject'] = 'test_subject'
1296+
1297+
smtp.connect(HOST, self.port)
1298+
smtp.send_message(msg)
1299+
self.assertIn('size', smtp.esmtp_features)
1300+
smtp.quit()
1301+
12681302
def test_with_statement(self):
12691303
with smtplib.SMTP(HOST, self.port) as smtp:
12701304
code, message = smtp.noop()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :meth:`smtplib.SMTP.close` not resetting the EHLO state, so an
2+
:class:`!SMTP` object reconnected with :meth:`~smtplib.SMTP.connect` sent
3+
``MAIL FROM`` without a new EHLO.

0 commit comments

Comments
 (0)