tags:

views:

28

answers:

1

I need to generate a multipart/mime message to send as a response to a HTTP request but am hitting either a bug or limitation in the Python email.* package.

The problem is that using Python 2.6, the message.as_string() call below generates a string with \n rather that CRLF as the line endings:

message = MIMEMultipart()
for image in images:
    f = image.open('rb')
    img = MIMEImage(f.read(), _encoder=encode_7or8bit)
    message.attach(img)


message.as_string()

There doesn't seem to be any way to persuade it to use the (MIME standard) CRLF. The Generator class that seems it should be able to do this, doesn't.

What have other people done to get round this?

A: 

What about a simple hack

message.as_string().replace('\n', '\r\n')

? Inelegant, but should work (and a bug report should be entered at the Python tracker).

Alex Martelli
Thought of that, but if there's \n characters in the body (which is a PNG file, so straight binary) then this will screw it up.AFAICT, the encode_7_or_8bit doesn't do anything clever to byte-stuff \n characters.
Malcolm Box
Oh there's already a bug here: http://bugs.python.org/issue1349106 It's been open since 2005 and for reasons I don't understand seems to be being resisted.
Malcolm Box
@Malcolm, by the time you replace newlines, the body's already been coded in some mail-acceptable way, which "straight binary" is most definitely **not** -- it would violate many RFCs. An encoding that doesn't actually and carefully "modify the payload" to make it RFC-compliant is unacceptable, and using it is _your_ bug, not Python's -- use `encode_base64` for binary payloads!
Alex Martelli
@Alex: Actually, binary is entirely MIME compliant as a transfer encoding - see e.g. http://tools.ietf.org/html/rfc2045#section-5.2 - but not for transmission over SMTP. But I'm not sending this over SMTP but over HTTP, which is perfectly happy to ship binary data.The bug is definitely Python's - it is assuming that all MIME will be transport encoded e.g. by the SMTP layer, but that isn't the case.
Malcolm Box
@Malcolm, you're right, by the letter of the RFCs. However, you did ask "what have other people done", and base64 encoding + the hack I mentioned is no doubt the popular workaround.
Alex Martelli