Frage

Python 3.2, Apache, no framework

I have a form to upload a file:

<form action="Files/Admin/Upload" method="post" enctype="multipart/form-data">
    <input type="file" name="upload_file" style="width:100%">
    <input type="submit" class="button" value="Upload">
</form>

There's also a few select boxes, but I didn't want to confuse the issue. The end goal is to encrypt the given file, and store it somewhere, which will then be decrypted later and given back. I managed to get the encrypt/decrypt working, but instead of a pdf file, I ended up with a byte string (opened in a browser it said:

b'%PDF-1.4 %âãÏÓ <snip...>

So I stripped out the encryption and decryption and saving, and I'm now just trying to make it give me back the exact file I just uploaded:

import cgi
tmp = cgi.FieldStorage()
dat = tmp['upload_file']
import mimetypes
gtype,encoding = mimetypes.guess_type(dat.filename)
print ('Content-type:', gtype+'\n')
print (dat.file.read())

That gives me:

Adobe Error

I've tried it with two different pdfs, now, and both give the same message.

A text file gives back a byte string of the original text:

b'STUFF - \xa7112.7\r\n1\r\nSTUFF\r\n8\r\nSTUFF <snip...>

Changing the code to include disposition:

import cgi
tmp = cgi.FieldStorage()
dat = tmp['upload_file']
import mimetypes
gtype,encoding = mimetypes.guess_type(dat.filename)
print ('Content-type:', gtype)
print ('Content-Disposition: attachment; filename="'+dat.filename+'"\n')
print (dat.file.read())

and using the text file gives me the usual download or save, but the text file is just the same byte string, not the actual file.

I've spent the last day trying to find the exact right combination of words that will make Google give me the answer, but of the (very few, surprisingly) results that are at all applicable, they all act as if this is an elementary operation and should just work. I've found stuff talking about reading from binary files and to open them correctly, except the uploaded file is a temp file, not a saved file, it's in memory and open is not a valid method for it. I've also seen stuff on setting up file servers in python, but they're talking about setting up actual servers, not just spitting out a a single file. Do I need to set up a full blown server to get back a file?

I'm sure I'm making some incredibly stupid rookie mistake, here, but I just can't figure out what.

War es hilfreich?

Lösung

print always includes an additional newline, which breaks the binary PDF file. Pass the end= parameter or write to sys.stdout:

#!/usr/bin/env python3
import sys
import cgi
tmp = cgi.FieldStorage()
dat = tmp['upload_file']
import mimetypes
gtype,encoding = mimetypes.guess_type(dat.filename)

sys.stdout.buffer.write (b'Content-type:' + gtype.encode('ascii') + b'\r\n\r\n')
sys.stdout.buffer.write (dat.file.read())
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top