2013-09-25 1 views
0

Я пытаюсь кодировать двоичный файл с MIMEApplication в Python 3.3, как часть многопоточного MIME HTTP POST. У меня проблема, что символ 0x0d интерпретируется как новая строка 0xa, несмотря на то, что все установлено в двоичные байты.Создание многочастного MIME-сообщения с двоичным компонентом для HTTP-запроса в Python 3

Вот минимальный тестовый сценарий, с двоичной строки с 0x0D в нем, получая неправильно:

from email.encoders import encode_noop 
from email.generator import BytesGenerator 
from email.mime.application import MIMEApplication 
import io 

app = MIMEApplication(b'Q\x0dQ', _encoder=encode_noop) 
b = io.BytesIO() 
g = BytesGenerator(b) 
g.flatten(app) 
for i in b.getvalue()[-3:]: 
    print("%02x " % i, end="") 
print() 

Выход: 51 0a 51, когда он должен быть 51 0d 51

Обратите внимание, что это для генерации двоичная часть для сообщения о множественном http POST.

ответ

0

я был в состоянии решить мою проблему, поставив манекен «маркер» в качестве содержимого MIMEApplication, подставляя в реальном двоичном текст после формирования сообщения MIME:

from email.encoders import encode_noop 
from email.generator import BytesGenerator 
from email.mime.application import MIMEApplication 
import io 

# Actual binary "file" I want to encode (in real life, this is a file read from disk) 
bytesToEncode = b'Q\x0dQ' 

# unique marker that we can find and replace after message generation 
binarymarker = b'GuadsfjfDaadtjhqadsfqerasdfiojBDSFGgg' 

app = MIMEApplication(binarymarker, _encoder=encode_noop) 
b = io.BytesIO() 
g = BytesGenerator(b) 
g.flatten(app, linesep='\r\n') # linesep for HTTP-compliant header line endings 

# replace the marker with the actual binary data, then you have the output you want! 
body = b.getvalue().replace(binarymarker, bytesToEncode) 

после этого body имеет значение, я хочу, не портя двоичные байты:

b'Content-Type: application/octet-stream\r\nMIME-Version: 1.0\r\n\r\nQ\rQ' 

Для сообщения с несколькими частями вы сначала собираете многостраничное сообщение, а затем выполняете функцию replace() в конце.

1

Попробуйте следующее (не уточняя кодировщик, используя base64 по умолчанию кодировщик):

import email 
from email.encoders import encode_noop 
from email.generator import BytesGenerator 
from email.mime.application import MIMEApplication 
import io 

app = MIMEApplication(b'Q\x0dQ') 
b = io.BytesIO() 
g = BytesGenerator(b) 
g.flatten(app) 
msg = email.message_from_bytes(b.getvalue()) 
assert msg.get_payload(decode=True) == b'Q\x0dQ' 
+0

Спасибо! Вы правы, это отвечает на вопрос, как было задано. Но знаете ли вы, как я могу использовать это как часть многопоточного сообщения MIME? Вот как мне на самом деле нужно это использовать. – Nils