victorcampos
victorcampos

Reputation: 1390

Building a multipart/form-data with binary image data in Django gives me a UnicodeDecodeError

--- Edited below with some more testing, please read :) ---

I'm struggling trying to build a multipart/form-data body in Python, basically I'm doing it with a buffer of strings in a list and then trying to join them, here's the code:

fp = open(filename, 'rb')

BOUNDARY = 's0m3r4ndomB0unD4ry'
body = []

body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="image"; filename="%s"' % filename)
body.append('Content-Type: %s' % file_type)
body.append('')
body.append(fp.read())
body.append('--' + BOUNDARY + '--')
body.append('')
fp.close()
body = '\r\n'.join(body)

It seemed simple in the beginning and this code works in a Python shell, but when integrating with my Django app it simply throws me an UnicodeDecodeError with this message: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)

I can't figure why this would happen only inside the Django app and not in the shell, could someone enlighten me?

EDIT: After some testing I find out that the recipe in ActiveState's site has a comment with a workaround:

body = CRLF.join([element.decode('string_escape') for element in L])

It stopped the UnicodeDecodeError from being thrown, but messes with some images, so it's not a fix for me :/

What's weird is that it only occurs in a Django web app, if I run the same command from the python manage.py shell it will work as expected, even without the above mentioned fix.

Does anyone knows what environment difference between the shell and the webserver may cause this problem?

Upvotes: 2

Views: 2126

Answers (1)

robots.jpg
robots.jpg

Reputation: 5161

You are most likely providing all str values when you test your code from the shell, while the Django app is returning form values (such as the filename) as unicode. Your join statement then attempts to convert the read file contents from str to unicode when joining them to the rest of the body, which throws the error.

Either check the type of everything appended to the body to see if this is the case, or try converting each segment of body to str before the join:

body = [str(seg) for seg in body]
body = '\r\n'.join(body)

Upvotes: 4

Related Questions