Возвращение байтового объекта вместо загруженного файла
Python 3.2, Apache, без фреймворка
У меня есть форма для загрузки файла:
<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>
Есть также несколько полей выбора, но я не хотел путать проблему. Конечная цель - зашифровать данный файл и сохранить его где-нибудь, который затем будет расшифрован позже и возвращен. Мне удалось заставить работать шифрование / дешифрование, но вместо файла PDF я получил строку байтов (открытую в браузере:
b'%PDF-1.4 %âãÏÓ <snip...>
Поэтому я убрал шифрование, дешифрование и сохранение, и сейчас я просто пытаюсь заставить его вернуть мне именно тот файл, который я только что загрузил:
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())
Это дает мне:
Я попробовал это с двумя различными PDF-файлами, и оба дают одно и то же сообщение.
Текстовый файл возвращает строку байтов исходного текста:
b'STUFF - \xa7112.7\r\n1\r\nSTUFF\r\n8\r\nSTUFF <snip...>
Изменение кода, чтобы включить расположение:
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())
и использование текстового файла дает мне обычную загрузку или сохранение, но текстовый файл - это та же строка байтов, а не фактический файл.
Я провел последний день, пытаясь найти точную правильную комбинацию слов, которая заставит Google дать мне ответ, но из (очень немного, удивительно) результатов, которые вообще применимы, все они действуют так, как будто это элементарно операция и должна просто работать. Я нашел материал, говорящий о чтении из двоичных файлов и об их правильном открытии, за исключением того, что загруженный файл - это временный файл, а не сохраненный файл, он находится в памяти и открытие не является допустимым методом для него. Я также видел материал по настройке файловых серверов в Python, но они говорят о настройке реальных серверов, а не просто выплевывании одного файла. Нужно ли настраивать полноценный сервер, чтобы вернуть файл?
Я уверен, что совершаю невероятно глупую ошибку новичка, но я просто не могу понять, что.
1 ответ
print
всегда включает дополнительную новую строку, которая разрывает двоичный файл PDF. Пройти end=
параметр или запись в 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())