[Python-bugs-list] [ python-Bugs-487310 ] smtplib mishandles SMTP disconnects

noreply@sourceforge.net noreply@sourceforge.net
Wed, 05 Dec 2001 15:44:38 -0800


Bugs item #487310, was opened at 2001-11-29 16:35
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=487310&group_id=5470

Category: Python Library
Group: Python 2.1.1
Status: Open
Resolution: None
Priority: 5
Submitted By: Fazal Majid (majid)
Assigned to: Barry Warsaw (bwarsaw)
Summary: smtplib mishandles SMTP disconnects

Initial Comment:
smtplib handles SMTP disconnects (e.g. timeouts)
inconsistently. The smtplib.SMTP.send() method does not
reset self.file on a socket error, unlike getreply(),
and thus a close() is necessary for in one case but not
in the other.

Recommendation: have smtplib.SMTP.send() call close()
on socket.error just as smtplib.SMTP.getreply() does on
EOF on self.file.

In the following test case, I have set the SMTP timeout
on my local machine to 10 seconds:

Python 2.1.1 (#1, Nov  7 2001, 16:18:10)
[GCC 2.95.3 20010315 (release)] on sunos5
Type "copyright", "credits" or "license" for more
information.
>>> import smtplib
>>> s = smtplib.SMTP('localhost', 25)
>>> import time
>>> time.sleep(10)
>>> s.sendmail('fmajid@kefta.com', 'fmajid@kefta.com',
'...')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.1/smtplib.py", line 469,
in sendmail
    (code,resp) = self.helo()
  File "/usr/local/lib/python2.1/smtplib.py", line 305,
in helo
    self.putcmd("helo", socket.getfqdn())
  File "/usr/local/lib/python2.1/smtplib.py", line 249,
in putcmd
    self.send(str)
  File "/usr/local/lib/python2.1/smtplib.py", line 239,
in send
    raise SMTPServerDisconnected('Server not connected')
smtplib.SMTPServerDisconnected: Server not connected
>>> s.connect('localhost', 25)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.1/smtplib.py", line 226,
in connect
    (code,msg)=self.getreply()
  File "/usr/local/lib/python2.1/smtplib.py", line 271,
in getreply
    raise SMTPServerDisconnected("Connection
unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly
closed
>>> s.connect('localhost', 25)
(220, 'bayazid.kefta.com ESMTP Postfix')


----------------------------------------------------------------------

>Comment By: Fazal Majid (majid)
Date: 2001-12-05 15:44

Message:
Logged In: YES 
user_id=110477

Oops... forgot to check the checkbox for attachments.

----------------------------------------------------------------------

Comment By: Fazal Majid (majid)
Date: 2001-12-05 15:42

Message:
Logged In: YES 
user_id=110477

I am attaching a patch that calls self.close() before
raising the SMTPServerDisconnected exception.

There does not seem to be a standard unit test for smtplib.
I have run this patch through a unit test of my own that
exercises smtplib. I don't have a way to test a broken MTA
that disconnects on EHLO, however.


----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-12-04 08:45

Message:
Logged In: YES 
user_id=6380

Can you please supply a patch?

Upload a context diff, don't forget to check the file upload
checkbox.

----------------------------------------------------------------------

Comment By: Fazal Majid (majid)
Date: 2001-11-30 07:04

Message:
Logged In: YES 
user_id=110477

I forgot to mention a workaround: if you catch
SMTPServerDisconnected, call self.close(). The operation is
idempotent so it isn't a problem if you do it twice, for
instance if the exception occurs in getreply().

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=487310&group_id=5470