From b6ec8222e8e36ccbc47852196d07387929539e27 Mon Sep 17 00:00:00 2001 From: huangzhenpc Date: Wed, 26 Feb 2025 13:54:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=82=AE=E4=BB=B6=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F:=201.=E5=A4=84=E7=90=86=E6=94=B6=E4=BB=B6=E4=BA=BA?= =?UTF-8?q?=E4=B8=BANone=E7=9A=84=E6=83=85=E5=86=B5=202.=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?SMTP=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=AF=B9=E7=A9=BA=E6=94=B6?= =?UTF-8?q?=E4=BB=B6=E4=BA=BA=E7=9A=84=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/mail_store.py | 8 +++++- app/services/smtp_server.py | 53 +++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/app/services/mail_store.py b/app/services/mail_store.py index 6d56637..0116ba5 100644 --- a/app/services/mail_store.py +++ b/app/services/mail_store.py @@ -84,7 +84,13 @@ class MailStore: try: # 查找收件人对应的邮箱 mailbox_id = None - recipients_list = recipients if isinstance(recipients, list) else [recipients] + + # 处理recipients为None的情况 + if recipients is None: + logging.warning("收件人列表为None,将使用空列表") + recipients_list = [] + else: + recipients_list = recipients if isinstance(recipients, list) else [recipients] # 确保收件人列表不为空 if not recipients_list: diff --git a/app/services/smtp_server.py b/app/services/smtp_server.py index f966452..3939fe0 100644 --- a/app/services/smtp_server.py +++ b/app/services/smtp_server.py @@ -39,36 +39,49 @@ class EmailHandler(Message): async def handle_DATA(self, server, session, envelope): """处理邮件数据""" try: - # 获取邮件数据 - message_data = envelope.content.decode('utf-8', errors='replace') + logging.info(f"收到邮件: 发件人={envelope.mail_from}, 收件人={envelope.rcpt_tos}") - # 记录接收到的邮件 - sender = envelope.mail_from - recipients = envelope.rcpt_tos + # 检查收件人列表是否有效 + if not envelope.rcpt_tos: + logging.warning("收到邮件但没有有效收件人,将拒绝") + return '550 无效的收件人' - logging.info(f"SMTP服务收到邮件: 发件人={sender}, 收件人={recipients}") + # 保存原始邮件数据 + raw_data = envelope.content.decode('utf-8', errors='replace') - # 使用email.parser解析邮件 - parser = email.parser.Parser(policy=default) - message = parser.parsestr(message_data) + # 解析邮件数据 + message = email_parser.Parser(policy=default).parsestr(raw_data) + subject = message.get('Subject', '') + logging.info(f"邮件主题: {subject}") - # 保存邮件 - success, result_message = await self.mail_store.save_email(message, sender, recipients, message_data) + # 记录邮件结构和内容 + logging.debug(f"邮件结构: is_multipart={message.is_multipart()}") + if message.is_multipart(): + logging.debug(f"多部分邮件: 部分数量={len(list(message.walk()))}") + for i, part in enumerate(message.walk()): + content_type = part.get_content_type() + logging.debug(f"部分 {i+1}: 内容类型={content_type}") + + # 使用邮件存储服务保存邮件 + success, error_msg = await self.mail_store.save_email( + message, + envelope.mail_from, + envelope.rcpt_tos, + raw_data=raw_data + ) if success: - logging.info(f"邮件已成功保存: {result_message}") - return '250 Message accepted for delivery' + logging.info(f"邮件保存成功: 来自 {envelope.mail_from} 发送给 {envelope.rcpt_tos}") + return '250 消息接收完成' else: - logging.error(f"邮件保存失败: {result_message}") - # 注意:即使保存失败,我们仍然返回成功,避免发件方重试 - # 这是因为问题通常在我们的系统中,重试不会解决问题 - return '250 Message accepted for delivery (warning: internal processing error)' - + logging.error(f"邮件保存失败: {error_msg}") + # 即使保存失败,也返回成功状态码,避免邮件服务器重试 + return '250 消息已收到' + except Exception as e: logging.error(f"处理邮件时出错: {str(e)}") traceback.print_exc() - # 返回临时错误,让发件方可以重试 - return '451 Requested action aborted: local error in processing' + return '451 处理邮件时出现错误,请稍后重试' # 为Windows环境自定义SMTP控制器