type plain form disposition data content application http file upload http-headers browser

http - plain - multipart form data file upload



Tamaño del archivo cargado (3)

¿Los navegadores web envían el tamaño del archivo en el encabezado http al cargar un archivo al 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?


  1. No estoy seguro, pero no deberías 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.


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

Se recomienda a los clientes HTTP que suministren la longitud del contenido para la entrada general de archivos para que un servidor ocupado pueda detectar si los datos del archivo propuesto son demasiado grandes para ser procesados ​​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".


EDITAR: antes de ir demasiado lejos, es posible que desee comprobar esta otra respuesta basándose en la configuración de Apache: Usar jQuery, restringir el tamaño del archivo antes de cargar . 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.

Aquí hay un ejemplo de encabezado que proviene de un formulario con el 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 )

Tiene el Content-Length en el encabezado, y adicionalmente está el Content-Type en el encabezado de la parte del archivo (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 quiere el contenido proporcionado y detiene la carga, no tiene más remedio que cerrar brutalmente el zócalo. 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 casos de comprobaciones asincrónicas en segundo plano (utilizando un temporizador que verifique el campo del archivo). Entonces tuve ese truco:

  • Yo uso jquery para decirme si el campo del archivo ha cambiado
  • Cuando se elige un nuevo archivo, desactive todos los demás campos de archivos en el mismo formulario para obtener solo ese.
  • Envíe el archivo de forma asincrónica (jQuery puede hacerlo por usted, utiliza un marco oculto)
  • En el lado del servidor, verifique el encabezado (contenido-longitud, tipo de contenido, ...), corte la conexión tan pronto como obtenga lo que necesita.
  • Establezca una variable de sesión que indique si ese archivo era correcto o no.
  • Del lado del cliente, como el archivo se carga en un marco , ni siquiera recibe ningún tipo de comentarios si la conexión se cierra . 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.

Muy sucio, ¿eh? Si alguno de ustedes tiene una mejor alternativa, soy todo oídos.