partir lista leer ejercicios desde crear con binarios binario archivos archivo python python-3.x binary zip cgi

lista - ¿Cómo implementar archivos zip(u otros binarios) a través de cgi en Python?



leer archivos bin en python (3)

El encabezado está mal formado porque, por alguna razón, Python lo envía después de enviar el archivo.

Lo que debe hacer es eliminar el stdout inmediatamente después del encabezado:

sys.stdout.flush()

Luego ponga la copia del archivo

Estoy codificando un pequeño sitio web con Python y CGI donde los usuarios pueden cargar archivos zip y descargar archivos cargados por otros usuarios. Actualmente puedo subir correctamente el zip, pero tengo problemas para enviar correctamente los archivos al usuario. Mi primer acercamiento fue:

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()

Pero pronto me di cuenta de que tenía que enviar el archivo como binario, así que lo intenté:

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'') )

Y diferentes variantes de eso. Simplemente no funciona; Apache genera el error "encabezado mal formado del script", así que supongo que debería codificar el archivo de alguna otra manera.


Debe imprimir una línea vacía después de los encabezados, y su encabezado Content-disposition no tiene el tipo ( attachment ):

print("Content-type: application/octet-stream") print("Content-Disposition: attachment; filename=%s.zip" %(filename)) print()

Es posible que también desee utilizar un método más eficiente para cargar el archivo resultante; use shutil.copyfileobj() para copiar los datos a 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)

No debe usar print() para datos binarios en ningún caso; todo lo que obtienes es b''...'' byte sintaxis literal. El objeto sys.stdout.buffer es el búfer de E / S binario subyacente, copia datos binarios directamente a eso.


Esto es lo que funcionó para mí, estoy ejecutando Apache2 y cargando este script a través de cgi. Python 3 es mi lenguaje.

Es posible que deba reemplazar la primera línea con la ruta de su pitón 3 bin.

#!/usr/bin/python3 import cgitb import cgi from zipfile import ZipFile import sys # Files to include in archive source_file = ["/tmp/file1.txt", "/tmp/file2.txt"] # Name and Path to our zip file. zip_name = "zipfiles.zip" zip_path = "/tmp/{}".format(zip_name) with ZipFile( zip_path,''w'' ) as zipFile: for f in source_file: zipFile.write(f); # Closing File. zipFile.close() # Setting Proper Header. print ( ''Content-Type:application/octet-stream; name="{}"''.format(zip_name) ); print ( ''Content-Disposition:attachment; filename="{}"/r/n''.format(zip_name) ); # Flushing Out stdout. sys.stdout.flush() bstdout = open(sys.stdout.fileno(), ''wb'', closefd=False) file = open(zip_path,''rb'') bstdout.write(file.read()) bstdout.flush()