浏览代码

try to fix Message.as_bytes() by trying different policies

Son NK 4 年之前
父节点
当前提交
dc8c2f403e
共有 2 个文件被更改,包括 15 次插入2 次删除
  1. 13 0
      app/email_utils.py
  2. 2 2
      email_handler.py

+ 13 - 0
app/email_utils.py

@@ -528,3 +528,16 @@ def parseaddr_unicode(addr) -> (str, str):
 def copy(msg: Message) -> Message:
     """return a copy of message"""
     return email.message_from_bytes(msg.as_bytes())
+
+
+def to_bytes(msg: Message):
+    """replace Message.as_bytes() method by trying different policies"""
+    try:
+        return msg.as_bytes()
+    except UnicodeEncodeError:
+        LOG.warning("as_bytes fails with default policy, try SMTP policy")
+        try:
+            return msg.as_bytes(policy=email.policy.SMTP)
+        except UnicodeEncodeError:
+            LOG.warning("as_bytes fails with SMTP policy, try SMTPUTF8 policy")
+            return msg.as_bytes(policy=email.policy.SMTPUTF8)

+ 2 - 2
email_handler.py

@@ -88,7 +88,7 @@ from app.email_utils import (
     parseaddr_unicode,
     send_email_with_rate_control,
     get_email_domain_part,
-    copy,
+    copy, to_bytes,
 )
 from app.extensions import db
 from app.greylisting import greylisting_needed
@@ -1244,7 +1244,7 @@ async def handle(envelope: Envelope, smtp: SMTP) -> str:
 
 
 async def get_spam_score(message: Message) -> float:
-    sa_input = message.as_bytes()
+    sa_input = to_bytes(message)
 
     # Spamassassin requires to have an ending linebreak
     if not sa_input.endswith(b"\n"):