saving octet-stream png file

Larry Martell larry.martell at gmail.com
Mon Aug 22 12:50:34 EDT 2016


On Mon, Aug 22, 2016 at 10:36 AM, Larry Martell <larry.martell at gmail.com> wrote:
> On Fri, Aug 19, 2016 at 4:24 PM, Chris Kaynor <ckaynor at zindagigames.com> wrote:
>> On Fri, Aug 19, 2016 at 12:00 PM, Larry Martell <larry.martell at gmail.com>
>> wrote:
>>
>>> On Fri, Aug 19, 2016 at 1:24 PM, Chris Angelico <rosuav at gmail.com> wrote:
>>> > On Sat, Aug 20, 2016 at 3:10 AM, Larry Martell <larry.martell at gmail.com>
>>> wrote:
>>> >> I have some python code (part of a django app) that processes a
>>> >> request that contains a png file. The request is send with
>>> >> content_type = 'application/octet-stream'
>>> >>
>>> >> In the python code I want to write this data to a file and still have
>>> >> it still be a valid png file.
>>> >>
>>> >> The data I get looks like this:
>>> >>
>>> >> u'\ufffdPNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\ufffd\
>>> x00\x00\x01\ufffd
>>> >> ......'
>>> >>
>>> >> If I try and write that to a file it fails with a UnicodeEncodeError.
>>> >> If I write it with encode('utf8') it writes the file, but then it's no
>>> >> longer a valid png file.
>>> >>
>>> >> Anyone know how I can do this?
>>> >
>>> > At that point, you've already lost information. Each U+FFFD (shown as
>>> > "\ufffd" above) is a marker saying "a byte here was not valid UTF-8"
>>> > (or whatever was being used). Something somewhere took the .png file's
>>> > bytes and tried to interpret them as text, which they're not.
>>> >
>>> > What sent you that data? How did you receive it?
>>>
>>> The request is sent by a client app written in C++ with Qt. It's
>>> received by a django based server. I am trying to port a falcon server
>>> to django. The falcon server code did this:
>>>
>>> form = cgi.FieldStorage(fp=req.stream, environ=req.env)
>>>
>>> and then wrote the png like this:
>>>
>>> fd.write(form[key].file.read())
>>>
>>> Whereas in the django server I am doing:
>>>
>>> fd.write(request.POST[key])
>>>
>>> I've never used the cgi module. I guess I can try that. I've written a
>>> lot with django but never had to receive a PNG file.
>>>
>>>
>> I don't know Django, however a quick search makes it seem like you might
>> need to use request.FILES[key] (1) rather than request.POST[key]. You may
>> also be able to use request.POST if you set request.encoding first (2). If
>> both of those fail, you may need to use request.body and parse the HTTP
>> form data manually, though I'd imagine there is an easier way.
>>
>> [1]
>> https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.HttpRequest.FILES
>>
>> [2]
>> https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.HttpRequest.encoding
>
> Thanks for the reply. When I get the request, request.FILES is empty.
> Yet the content type is multipart/form-data and the method is POST:
>
> (Pdb) print request.META['CONTENT_TYPE']
> multipart/form-data;
> boundary="boundary_.oOo._NzEwNjIzMTM4MTI4NjUxOTM5OQ==MTY2NjE4MDk5Nw=="
>
> (Pdb) print request.META['REQUEST_METHOD']
> POST
>
> (Pdb) print request.FILES
> <MultiValueDict: {}>
>
> Tried setting request.encoding, but that messes up the request structure:
>
> (Pdb) type(request.POST[key])
> <type 'unicode'>
> (Pdb) request.encoding = "iso-8859-1"
> (Pdb) type(request.POST[key])
> *** MultiValueDictKeyError:
> "u'right-carotidartery:63B2E474-D690-445F-B92A-31EBADDC9D93.png'"


Thanks to everyone for they replied. I solved this by changing the
client to set the file and filename fields each part of the multipart
and then I was able it iterate through request.FILES and successfully
write the files as PNG.



More information about the Python-list mailing list