Issue16005
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2012-09-23 12:21 by DDarko, last changed 2022-04-11 14:57 by admin. This issue is now closed.
Messages (9) | |||
---|---|---|---|
msg171029 - (view) | Author: DDarko (DDarko) | Date: 2012-09-23 12:21 | |
I'm trying to send an email as follows: smtp = smtplib.SMTP(host, port=25) smtp.ehlo() smtp.sendmail(from_mail, to_mail, data) The last line / command calls the raise. I would like to know the reason why SMTP did not accept my email? In theory, enough to capture the exception. However, the exception of the last line returns: "smtplib.SMTPServerDisconnected: Connection unexpectedly closed" This is because the smtplib get replies in: http://hg.python.org/cpython/file/default/Lib/smtplib.py 767 (code, resp) = self.data(msg) Then performs: 769 self.rset() As a result, the SMTP server disconnects the client. And instead receive info with reason I have information about sudden disconnection. I do not think it should be reset, and if it is wrapped in a try. Working snippet: (code, resp) = self.data(msg) if code != 250: #self.rset() raise SMTPDataError(code, resp) #if we got here then somebody got our mail return senderrs This happens on servers mx.google.com |
|||
msg171031 - (view) | Author: Christian Heimes (christian.heimes) * ![]() |
Date: 2012-09-23 13:00 | |
According to RFC 821 a smtp server must always apply with OK when it receives a RSET command. RESET (RSET) This command specifies that the current mail transaction is to be aborted. Any stored sender, recipients, and mail data must be discarded, and all buffers and state tables cleared. The receiver must send an OK reply. It seems like your mail server violates the standards. |
|||
msg171034 - (view) | Author: DDarko (DDarko) | Date: 2012-09-23 13:17 | |
The problem is that this is not my SMTP server. I want to connect as a client with smtplib. For this, as I said earlier it is mx.google.com send: 'ehlo [127.0.1.1]\r\n' reply: b'250-mx.google.com at your service, [MYIP]\r\n' reply: b'250-SIZE 35882577\r\n' reply: b'250-8BITMIME\r\n' reply: b'250-STARTTLS\r\n' reply: b'250 ENHANCEDSTATUSCODES\r\n' reply: retcode (250); Msg: b'mx.google.com at your service, [MYIP]\nSIZE 35882577\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES' send: 'mail FROM:<EMAIL> size=448\r\n' reply: b'250 2.1.0 OK o7si11249316wiz.31\r\n' reply: retcode (250); Msg: b'2.1.0 OK o7si11249316wiz.31' send: 'rcpt TO:<EMAIL>\r\n' reply: b'250 2.1.5 OK o7si11249316wiz.31\r\n' reply: retcode (250); Msg: b'2.1.5 OK o7si11249316wiz.31' send: 'data\r\n' reply: b'354 Go ahead o7si11249316wiz.31\r\n' reply: retcode (354); Msg: b'Go ahead o7si11249316wiz.31' data: (354, b'Go ahead o7si11249316wiz.31') send: b'Content-Type: multipart/related; boundary="===============0969887089=="\r\nMIME-Version: 1.0\r\nFrom: ....\r\n\r\n--===============0969887089==--\r\n.\r\n' reply: b'550-5.7.1 [MYIP 7] Our system has detected that this message is\r\n' reply: b'550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,\r\n' reply: b'550-5.7.1 this message has been blocked. Please visit\r\n' reply: b'550-5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for\r\n' reply: b'550 5.7.1 more information. o7si11249316wiz.31\r\n' reply: retcode (550); Msg: b'5.7.1 [MYIP 7] Our system has detected that this message is\n5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,\n5.7.1 this message has been blocked. Please visit\n5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for\n5.7.1 more information. o7si11249316wiz.31' data: (550, b'5.7.1 [MYIP 7] Our system has detected that this message is\n5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,\n5.7.1 this message has been blocked. Please visit\n5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for\n5.7.1 more information. o7si11249316wiz.31') send: 'rset\r\n' --- Connection unexpectedly closed |
|||
msg171060 - (view) | Author: R. David Murray (r.david.murray) * ![]() |
Date: 2012-09-23 16:48 | |
I believe that Google is technically out of compliance with the SMTP spec here. What they are doing is not unreasonable, since they don't have any reason to want to waste resources on talking to a server they think is spamming them. Making this work in a more useful fashion may be considered an enhancement rather than a bug fix, since arguably it is Google, not smtplib, that appears to be violating the RFC. On the other hand, the fix is simple enough, is unlikely to be harmful, and it can be argued that handling this error is the proper action for a robust smtp client in any case, so I think we can justify making it a bug fix. The rset is correct in the general case, so the fix would be to wrap it in a try/except and treat SMTPServerDisconnected as not-an-error. DDarko, would you have any interest in proposing a patch with tests? |
|||
msg171063 - (view) | Author: DDarko (DDarko) | Date: 2012-09-23 17:21 | |
I do not understand why at all reset is performed ? If moments later raise is done. If someone despite error SMTPSenderRefused, SMTPRecipientsRefused or SMTPDataError will still want to maintain a connection and use other data with session is likely he will call SMTP().rset() manually. In my opinion, the most frequent use of the library are: smtp = smtplib.SMTP(host, port=25) smtp.ehlo() try: smtp.sendmail(from_mail, to_mail, data) except Exception as e: print(e) smtp.quit() If you wish to use session despite the error: smtp = smtplib.SMTP(host, port=25) smtp.ehlo() for to_mail in mail_list: try: smtp.sendmail(from_mail, to_mail, data) except smtplib.SMTPRecipientsRefused as e: smtp.rset() print(e) smtp.quit() If we do not handle exception, reset does not matter. IMHO patch should look like this: http://hg.python.org/cpython/file/default/Lib/smtplib.py 745d744 < self.rset() 756d754 < self.rset() 760d757 < self.rset() |
|||
msg171071 - (view) | Author: R. David Murray (r.david.murray) * ![]() |
Date: 2012-09-23 18:04 | |
The rset just returns the connection to the "base" state, allowing a new message sending transaction to start from a known state. In any case, since the library has done this in the past, it must continue to do this in the future, or it will break currently working code. |
|||
msg171102 - (view) | Author: DDarko (DDarko) | Date: 2012-09-24 06:32 | |
I understand, in that case: /cpython/file/default/Lib/smtplib.py 760c760,761 < self.rset() --- > try: self.rset() > except: pass Solves the problem. |
|||
msg171123 - (view) | Author: R. David Murray (r.david.murray) * ![]() |
Date: 2012-09-24 13:29 | |
Well, a bare except is almost always a bad idea, and certainly is in this case. I'll create a patch for this if no one beats me to it. |
|||
msg223795 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014-07-23 23:31 | |
This bug is fixed (at least in 3.5) so you might want to close it. (See the _rset function in smtplib.py:482 and how its used in sendmail.) |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:57:36 | admin | set | github: 60209 |
2014-07-26 21:35:42 | r.david.murray | set | status: open -> closed superseder: error responses from server are masked in smtplib when server closes connection resolution: duplicate stage: resolved |
2014-07-23 23:31:21 | zvyn | set | nosy:
+ zvyn, jesstess messages: + msg223795 |
2012-09-24 13:29:41 | r.david.murray | set | messages: + msg171123 |
2012-09-24 06:32:43 | DDarko | set | messages: + msg171102 |
2012-09-23 18:04:14 | r.david.murray | set | messages: + msg171071 |
2012-09-23 17:21:31 | DDarko | set | messages: + msg171063 |
2012-09-23 16:48:41 | r.david.murray | set | messages: + msg171060 |
2012-09-23 13:17:28 | DDarko | set | messages: + msg171034 |
2012-09-23 13:00:56 | christian.heimes | set | nosy:
+ christian.heimes messages: + msg171031 |
2012-09-23 12:50:25 | r.david.murray | set | nosy:
+ barry, r.david.murray components: + email, - Library (Lib) |
2012-09-23 12:21:25 | DDarko | create |