slimta / python-slimta

Python libraries to send, receive, and queue email.
https://slimta.org/
MIT License
171 stars 43 forks source link

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd8 in position 54: ordinal not in range(128) #120

Open thestick613 opened 7 years ago

thestick613 commented 7 years ago
2017-03-08 21:35:42,844.844 ERROR socket - _log_error: fd:124:error address=('fmx.freemail.hu', 25) args=(1, u'[SSL: ...l.c:590)') message='[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)'
Traceback (most recent call last):
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/gevent/greenlet.py", line 536, in run
    result = self._run(*self.args, **self.kwargs)
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/slimta/relay/smtp/client.py", line 290, in _run
    relay_error = SmtpRelayError.factory(reply)
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/slimta/relay/smtp/__init__.py", line 50, in factory
    return SmtpTransientRelayError(reply)
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/slimta/relay/smtp/__init__.py", line 56, in __init__
    super(SmtpTransientRelayError, self).__init__('Transient', reply)
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/slimta/relay/smtp/__init__.py", line 42, in __init__
    type, command.decode('ascii'), str(reply))
  File "/root/venv_cpython_2017/local/lib/python2.7/site-packages/slimta/smtp/reply.py", line 114, in __bytes__
    self.message.encode('utf-8')))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd8 in position 54: ordinal not in range(128)
Wed Mar  8 21:35:42 2017 <SmtpRelayClient at 0x2acfcff16d70> failed with UnicodeDecodeError
cneberg commented 3 years ago

Try something like this. It fixed my issues with odd utf-8 in the Subject header.

diff --git a/slimta/util/pycompat.py b/slimta/util/pycompat.py
index f81edad..eea5dac 100644
--- a/slimta/util/pycompat.py
+++ b/slimta/util/pycompat.py
@@ -47,9 +47,14 @@ if PY3:

     from email.generator import BytesGenerator
     from email.parser import BytesParser
-    from email.policy import SMTP
-    parser = partial(BytesParser, policy=SMTP)
-    generator = partial(BytesGenerator, policy=SMTP)
+    from email.policy import compat32
+
+    # compat32 doesn't decode headers and leaves
+    # them as-is 7-bit - so less Unicode errors
+
+    custom = compat32.clone(linesep='\r\n')
+    parser = partial(BytesParser, policy=custom)
+    generator = partial(BytesGenerator, policy=custom)
 else:
     from itertools import imap
     map_func = imap