【问题标题】:ssl.SSLEOFError while sending emails through Django通过 Django 发送电子邮件时出现 ssl.SSLEOFError
【发布时间】:2018-01-09 16:05:37
【问题描述】:

设置

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_USE_TLS = True

EMAIL_HOST = 'smtp.gmail.com'

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER = 'no_reply@domain.com'

SERVER_EMAIL = 'no_reply@domain.com'

DEFAULT_DO_NOT_REPLY = 'User <no_reply@domain.com>'

EMAIL_HOST_PASSWORD = 'xxxxxxxxx'

EMAIL_PORT = 587

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

class EmailThread(threading.Thread):
    def __init__(self, subject, context, recipient, template):
        self.subject = subject
        self.recipient = recipient
        self.message = get_template(template).render(context)
        threading.Thread.__init__(self)

    def run(self):
        msg = EmailMessage(
            subject=self.subject,
            from_email=settings.DEFAULT_DO_NOT_REPLY,
            to=self.recipient,
            body=self.message
        )
        msg.content_subtype = "html"

        try:
            msg.send(fail_silently=False)
            log.info("E-mail triggered. Subject: '%s', to: %s" % (self.subject, self.recipient))
        except Exception as e:
            log.exception(e)

用法

def notify_admin_blocked_account(user):
    """
    Sends sends an email when the account is blocked
    :return:
    """
    email = EmailThread(
        subject='{}, your account has been blocked'.format(user),
        context={
            'user': user,
            'login_attempts': settings.MAX_STAFF_PWD_ATTEMPTS,
        },
        recipient=[user.email,],
        template='mail/notify_admin_blocked_account.html'
    )
    email.start()

错误

[ERROR][2017-08-01 10:40:26,835][mail] EOF occurred in violation of protocol (_ssl.c:645)
Traceback (most recent call last):
  File "./bin/mail.py", line 27, in run
    msg.send(fail_silently=False)
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/message.py", line 348, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 104, in send_messages
    new_conn_created = self.open()
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 69, in open
    self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile)
  File "/usr/lib/python3.5/smtplib.py", line 766, in starttls
    server_hostname=self._host)
  File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 752, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:645)

当我尝试使用 Django 发送电子邮件(异步)时,我有一些奇怪的行为。我真的很想避免安装第三方应用程序以减少代码碎片 - 特别是其中一些似乎使用 crontab 的应用程序。

值得注意的是,错误并非总是发生。然而,即使它没有发生,有时也不会发送电子邮件。只有一些人设法通过。

在我的开发环境中运行良好,我可以发送电子邮件。但是,在我的生产环境(EC2 实例)上,它根本不起作用。

如果我通过正常流程触发电子邮件,则不会发送。如果我登录到服务器,打开manage.py shell,导入一个项目并调用发送电子邮件的函数,有时我会收到触发和手动触发的电子邮件或收到错误(如下所示)。

【问题讨论】:

  • 有时安全组可能是问题所在。您的安全组中的端口可能未打开
  • 奇怪的是,有些电子邮件在生产环境中却能顺利通过。在开发中,它们都可以。这让我想知道问题是否出在 AWS 机器上。问题是:为什么某些电子邮件会发送而有些则不会。

标签: django django-email


【解决方案1】:

我的解决方案是使用Django-Mailer。它使项目碎片化,这是我想避免的,但它的使用非常简约。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多