I'm coding a small website with Python and CGI where users can upload zip files and download files uploaded by other users. Currently I'm able to upload correctly the zip's, but I'm having some trouble to correctly send files to the user. My first approach was:
file = open('../../data/code/' + filename + '.zip','rb')
print("Content-type: application/octet-stream")
print("Content-Disposition: filename=%s.zip" %(filename))
print(file.read())
file.close()
But soon I realized that I had to send the file as binary, so I tried:
print("Content-type: application/octet-stream")
print("Content-Disposition: filename=%s.zip" %(filename))
print('Content-transfer-encoding: base64\r')
print( base64.b64encode(file.read()).decode(encoding='UTF-8') )
And different variants of it. It just doesn't works; Apache raises "malformed header from script" error, so I guess I should encode the file in some other way.
You need to print an empty line after the headers, and you Content-disposition header is missing the type (attachment
):
print("Content-type: application/octet-stream")
print("Content-Disposition: attachment; filename=%s.zip" %(filename))
print()
You may also want to use a more efficient method of uploading the resulting file; use shutil.copyfileobj()
to copy the data to sys.stdout.buffer
:
from shutil import copyfileobj
import sys
print("Content-type: application/octet-stream")
print("Content-Disposition: attachment; filename=%s.zip" %(filename))
print()
with open('../../data/code/' + filename + '.zip','rb') as zipfile:
copyfileobj(zipfile, sys.stdout.buffer)
You should not use print()
for binary data in any case; all you get is b'...'
byte literal syntax. The sys.stdout.buffer
object is the underlying binary I/O buffer, copy binary data directly to that.
The header is malformed because, for some reason, Python sends it after sending the file.
What you need to do is flush stdout right after the header:
sys.stdout.flush()
Then put the file copy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With