2008-11-11 37 views
11

¿Los navegadores web envían el tamaño del archivo en el encabezado http al cargar un archivo en el servidor? Y si ese es el caso, entonces, ¿es posible rechazar el archivo simplemente leyendo el encabezado y no esperar a que termine todo el proceso de carga?Tamaño del archivo cargado

Respuesta

11

http://www.faqs.org/rfcs/rfc1867.html

clientes HTTP se anima a suministrar contenidos de longitud para la entrada de archivos en general para que un servidor ocupado podría detectar si los datos del archivo propuesto es demasiado grande para ser procesada razonablemente

Pero la longitud del contenido no es necesaria, por lo que no puede confiar en ello. Además, un atacante puede forjar una longitud de contenido incorrecta.

Leer el contenido del archivo es la única manera confiable. Habiendo dicho eso, si la longitud del contenido está presente y es demasiado grande, cerrar la conexión sería algo razonable.

Además, el contenido se envía como multiparte, por lo que la mayoría de los marcos modernos lo decodifican primero. Eso significa que no obtendrá el flujo de bytes de archivos hasta que el marco esté listo, lo que podría significar "hasta que se cargue todo el archivo".

1
  1. No estoy seguro, pero no debe confiar en nada enviado en el encabezado, ya que podría ser falsificado por el usuario.

  2. Depende de cómo funciona el servidor. Por ejemplo, en PHP su script no se ejecutará hasta que se complete la carga del archivo, por lo que esto no sería posible.

2

EDITAR: antes de ir demasiado lejos, es posible que desee comprobar esta otra respuesta basándose en la configuración de Apache: Using jQuery, Restricting File Size Before Uploading. la siguiente descripción solo es útil si realmente necesita más comentarios personalizados.

Sí, puede obtener cierta información por adelantado, antes de permitir la carga del archivo completo.

He aquí un ejemplo de cabecera procedente de un formulario con el atributo enctype="multipart/form-data":

POST/HTTP/1.1 
Host: 127.0.0.1:8000 
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.7,fr-be;q=0.3 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Content-Type: multipart/form-data; boundary=---------------------------886261531333586100294758961 
Content-Length: 135361 

-----------------------------886261531333586100294758961 
Content-Disposition: form-data; name=""; filename="IMG_1132.jpg" 
Content-Type: image/jpeg 

(data starts here and ends with -----------------------------886261531333586100294758961) 

Usted tiene el Content-Length en la cabecera, y, además, existe el tipo de contenido en la cabecera de la parte de archivos (cada archivo tiene su propio encabezado, que es el propósito de la codificación multiparte). Tenga en cuenta que es responsabilidad del navegador establecer un tipo de contenido relevante adivinando el tipo de archivo; no puede garantizarlo, pero debería ser bastante confiable para el rechazo temprano (sin embargo, es mejor que revise todo el archivo cuando esté completamente disponible).

Ahora, hay un gotcha. Solía ​​filtrar archivos de imágenes como ese, no en el tamaño, sino en el tipo de contenido; pero como desea detener la solicitud lo antes posible, surge el mismo problema: , el navegador solo obtiene su respuesta una vez que se envía toda la solicitud, incluido el contenido del formulario y, por lo tanto, los archivos cargados.

Si no desea el contenido proporcionado y detiene la carga, no tiene más remedio que cerrar brutalmente la toma. El usuario solo verá un confuso mensaje de "restablecimiento de conexión por pares". Y eso apesta, pero es por diseño.

Por lo tanto, solo desea utilizar este método en los casos de comprobaciones asincrónicas de fondo (utilizando un temporizador que verifique el campo del archivo). Así que tuve que cortar:

  • utilizo jQuery para decirme si el campo archivo ha cambiado
  • Cuando se elige un nuevo archivo, desactivar todos los demás campos de archivos en la misma forma para obtener sólo que uno .
  • Enviar el archivo de forma asíncrona (jQuery puede hacerlo por usted, se utiliza un marco oculto)
  • del lado del servidor, comprobar el encabezado (de longitud de contenido, tipo de contenido, ...), cortar la conexión tan pronto ya que tienes lo que necesitas
  • Establezca una variable de sesión que indique si ese archivo era correcto o no.
  • En el lado del cliente, como el archivo se carga en un marco , no recibe ningún tipo de comentarios si la conexión está cerrada. Tu única alternativa es un temporizador.
  • En el lado del cliente, un temporizador sondea el servidor para obtener un estado para el archivo cargado. Del lado del servidor, tiene esa variable de sesión configurada, envíela de vuelta al navegador.
  • El cliente tiene el código de estado; Preséntelo en su formulario: mensaje de error, marca de verificación verde/X roja, lo que sea. Restablezca el campo del archivo o deshabilite el formulario, usted decide. No olvide volver a habilitar otros campos de archivos.

Quite messy, eh? Si alguno de ustedes tiene una mejor alternativa, soy todo oídos.

Cuestiones relacionadas