2017-02-18 10 views
0

Я пишу скрипт Python для настройки сокета для отправки многостраничной электронной почты с изображением из моей учетной записи Gmail через SMTP. Я не использую smtplib или email.mime для образовательных целей. Я использую ssl и сокет и обертываю TCP-сокет с помощью ssl.wrap_socket.SMTP to Gmail: изображение повреждено добавлением CRLF

Все работает нормально, и сообщение электронной почты приходит как с текстом, так и с прикрепленным изображением. Однако приложенное изображение JPEG повреждено.

Сравнивая исходное изображение и поврежденное изображение в шестнадцатеричном редакторе, я вижу, что все байты 0x0D и 0x0A в jpeg были заменены на 0x0D0x0A. Эти байты будут представлять CR и LF в тексте, поэтому представляется, что в какой-то момент CR и LF заменяются CRLF некорректно в моих двоичных данных.

Бинарные данные выглядят правильными, если я пишу их в файл непосредственно перед отправкой в ​​сокет ssl. По-видимому, Gmail корректно интерпретирует Content-type, поскольку он отображает поврежденное изображение в качестве изображения.

Любые идеи, в которых замена CRLF может быть ползущей в данные двоичного изображения?

Решение:

Соответствующий код решение для заголовка кодирования:

 b'Content-Transfer-Encoding: base64\r\n' +\ 

И для самого base64 кодирования:

clientSocketSSL.sendall(base64.b64encode(msgImage)) 
+0

Возможно, вам следует использовать модули более высокого уровня, если вы не хотите изучать все детали протокола и позволить ему делать «правильные вещи». Если вы хотите использовать сокеты, то вставьте MIME RFC. – Cans

ответ

1

Поскольку вы не показывают какой-либо код моя догадка заключается в том, что вы просто помещаете двоичное изображение в почту. Но традиционно почта может передавать только данные ASCII и имеет ограничение длины строки в 1000 символов, поэтому данные должны быть закодированы для транспорта, см. Wikipedia:MIME для получения дополнительной информации.

Если вы не укажете какую-либо кодировку для транспорта, она будет обработана как 7 бит, и если вам повезет с 8-битным кодированием, и оба этих кодирования будут обрабатывать специальные концы линии и будут меняться в зависимости от платформы. Это означает, что в Windows исходный одиночный LF будет храниться как CRLF, а в Unix исходный CRLF будет храниться только как LF. Обратите внимание, что не только отправители и получатели почтовых пользователей могут адаптировать данные к платформе, но любой почтовый сервер между ними может также изменить их.

Вкратце: используйте MIME для правильного кодирования двоичных данных для транспорта, email предоставляет необходимые функции.

+0

Спасибо за подсказку о кодировании. См. Мои правки выше для того, что я сделал до сих пор, но я продолжу расследование этого. – TonyM

+0

@TonyM: это точно так, как я ожидал, т. Е. Надлежащего транспортного безопасного кодирования, такого как base64. Кроме того, вы должны рассматривать электронную почту как байты, а не как кодированные данные UTF-8. –

+0

Да, кодировка base64 решила это! – TonyM

Смежные вопросы