template simple page not found files error custom django file-upload error-handling upload custom-error-pages

simple - request.files django



Limite el tamaño del archivo de carga con Django y visualice la página de error (2)

Uso Django y me gustaría mostrar una página de error si la carga de un archivo excede el tamaño permitido sin cargar todo el contenido. Para esto, se utilizó un controlador de carga personalizado.

Por un lado, el controlador de carga comprueba la longitud total del contenido en el encabezado POST, además, se realiza un seguimiento de los fragmentos cargados y se suma su tamaño.

Lamentablemente, no sé cómo activar la generación de una página de error.

Mi primera idea fue devolver contenido POST y ARCHIVO vacío y detectar esto en la vista, pero esto no funciona.

from django.core.files.uploadhandler import FileUploadHandler, StopUpload from django.http import QueryDict from django.utils.datastructures import MultiValueDict class QuotaUploadHandler(FileUploadHandler): """ This test upload handler terminates the connection if more than a quota (5MB) is uploaded. """ QUOTA = 5 * 2**20 # 5 MB def __init__(self, request=None): super(QuotaUploadHandler, self).__init__(request) self.total_upload = 0 def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None): tmp_post = QueryDict('''', mutable=True) tmp_files = MultiValueDict() if content_length > self.QUOTA: META["ERROR"] = "File is larger than maximum." return tmp_post, tmp_files def receive_data_chunk(self, raw_data, start): self.total_upload += len(raw_data) if self.total_upload >= self.QUOTA: raise StopUpload(connection_reset=True) return raw_data def file_complete(self, file_size): return None class CustomUploadError(Exception): pass

¿Alguien puede ayudar?

Actualizar:

Otra solución que revisé fue algo como esto en la vista:

def main(request): request.upload_handlers.insert(0, QuotaUploadHandler()) content_length = request.META["CONTENT_LENGTH"] if content_length is not "" and int(content_length) > 5 * 1024 * 1024: print "Upload to large." raise Http404 return csrf_protected_main(request)

Comprobé el resultado con una captura wireshark: en este caso, la respuesta del servidor se sirve al cliente, pero el servidor Django restablece el socket TCP (presumiblemente porque todavía está recibiendo entrada).

POST / HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.24) Gecko/20111107 Ubuntu/10.10 (maverick) Firefox/3.6.24 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: de,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: http://localhost:8080/ Cookie: csrftoken=078fa2166ff190b148ac9045b3c408d7 Content-Type: multipart/form-data; boundary=---------------------------37071231519976700161208143859 Content-Length: 20971913 -----------------------------37071231519976700161208143859 Content-Disposition: form-data; name="testfile"; filename="test.test" Content-Type: application/octet-stream .... [36864 bytes missing in capture file] ....... HTTP/1.0 404 NOT FOUND Date: Sat, 10 Dec 2011 19:57:37 GMT Server: WSGIServer/0.1 Python/2.6.6 Content-Type: text/html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="en"> <head> ... [ongoing]

También traté de detener la carga con un código de respuesta HTTP 413 (archivo a gran tamaño), pero tampoco funcionó.


Tengo un campo como este:

class MyFileField(FileField): def clean(self, data): max_size = settings.MAX_SIZE_UPLOAD if data and max_size and len(data) > max_size: raise ValidationError(_(''File too large. Max size restricted to %s bytes'') % max_size) return super(MyFileField, self).clean(data)

Si el archivo tiene un tamaño superior a MAX_SIZE_UPLOAD, existe un error en el formulario


como han descrito otros comentaristas, si comprueba la longitud del contenido en la capa de Django, entonces ya ha terminado de cargar todo el archivo, que podría no ser demasiado bueno. si realmente desea detenerlo en el nivel del servidor de aplicaciones, algunos servidores web tienen una directiva que puede usar para informar a los clientes que han excedido los límites de tamaño de carga.

por ejemplo, el LimitRequestBody de Apache se puede usar para especificar la cantidad máxima de bytes permitidos para un cuerpo de solicitud. Yo uso esto en el httpd.conf de mi apache (para hacerlo ''global'') pero también puedes usar el LimitRequestBody en el nivel. en mi http.conf:

# limit requests to 25MB LimitRequestBody 26214400

cuando este límite es disparado por una solicitud, Apache devolverá un HTTP estándar específico utilizado para este propósito:

Error HTTP: 413 entidad de solicitud demasiado grande

dependiendo de cómo esté configurada su aplicación (¿usa JS en el cliente para realizar esa solicitud?), entonces puede manejar el error en el lado del cliente si se devuelve este error en particular.

HTH.