Stranger6667 / postmarker

Python client library for Postmark API
https://postmarker.readthedocs.io/en/stable/
MIT License
134 stars 29 forks source link

Library incorrectly quotes long lines when sent via API #76

Closed jdotjdot closed 7 years ago

jdotjdot commented 7 years ago

If large HTML files (particularly those with large lines, for example anything produced using MJML with the --min minification flag enabled) are sent using Postmarker, the HTML is escaped using quoted-printable and sent to Postmark's API that way, when it should actually be sent unquoted.

The reason this happens is under the hood, Postmarker calls the Django email backend's message.message() within EmailBackend.prepare_message(). This has the message turn itself into MIME, which then is later deconstructed back to a dict using Email.from_mime(). Since Django thinks it's serializing the email for an SMTP send, it automatically quotes the email or alternative attachment under certain circumstances (utf-8 + long lines, see django.core.mail.message.py:220) and sets the Content-Transfer-Encoding to quoted-printable. When Postmarker turns that back into a dict, it loses the Content-Transfer-Encoding header and does not unquote, leading to the quoted version being sent directly via Postmark's API and completely incorrect emails being sent, particularly if they include any Outlook-specific markup that uses XML namespaces and colons.

One way to fix this is when converting the MIME email back to a dictionary, to detect if it has been quoted and then to unquote using email.quoprimime.body_decode(...). Alternatively, the better way to fix this is to refactor simply not to let Django's mailing backend create the MIME email at all, and simply send the body and headers to Postmark via the API without doing any unnecessary processing. This is how djrill for Mandrill works, and emails I sent with Postmarker that got mangled were not mangled with djrill.

Stranger6667 commented 7 years ago

Hello @jdotjdot ! Thank you for the detailed report! I think, that anyway working with quoted-printable payload should be fixed for all MIME messages, since postmarker supports it. Here is the fix - #77

I agree, that it would be better not to do extra work like converting email to MIME and back, but in that case some headers will be lost, for example Date and Message-ID in Django 1.10. So, I have to do some investigations :)

jdotjdot commented 7 years ago

Thanks! I love how responsive you are.

Looking forward to seeing this pushed to PyPI.

Stranger6667 commented 7 years ago

You're very welcome! :) I'll make a release today - 0.6.1

Stranger6667 commented 7 years ago

Done! The new release is on PyPI :)