Pregunta

Estoy tratando de sopesar los pros y los contras de establecer la cabecera HTTP Content-Length frente a la utilización codificación fragmentada para volver [posiblemente] archivos de gran tamaño de mi servidor. Uno o el otro se necesita para ser compatible con HTTP 1.1 espec utilizando conexiones persistentes. Veo la ventaja de ser la cabecera Content-Length:

  • Descargar los cuadros de diálogo pueden mostrar precisa barra de progreso
  • Cliente conoce por adelantado si el archivo puede / no puede ser demasiado grande para que ellos ingieren

La desventaja es tener que calcular el tamaño antes de devolver el objeto que no siempre es práctico y podría añadir a la utilización del servidor / base de datos. La desventaja de codificación fragmentada es la pequeña sobrecarga de añadir el tamaño de fragmento antes de cada trozo y la barra de progreso de la descarga. ¿Alguna idea? Cualquier otra consideración HTTP para los dos métodos que no puede haber pensado?

¿Fue útil?

Solución

Uso Content-Length, sin duda. La utilización de los servidores de esta será casi inexistente y el beneficio para sus usuarios será grande.

Para el contenido dinámico, también es bastante simple para añadir soporte respuesta comprimida ( gzip ). Eso requiere búfer de salida, que a su vez le da la longitud del contenido. (No es práctico con las descargas de archivos o contenidos ya comprimida (sonido, imágenes)).

Tenga en cuenta también la adición de soporte para contenido parcial / porción de rango de bytes - es decir, la capacidad para reiniciar las descargas. Ver aquí un ejemplo de intervalo de bytes (el ejemplo es en PHP, pero es aplicable en cualquier idioma). Es necesario Content-Length al servir contenido parcial.

Por supuesto, esos no son balas de plata: para el streaming de medios de comunicación, no tiene sentido utilizar el almacenamiento en búfer de salida o tamaño de la respuesta; para archivos de gran tamaño, búfer de salida no tiene sentido, pero Content-Length y carga de bytes tiene mucho sentido (reiniciando una descarga no es posible).

En lo personal, me sirven Content-Length cada vez que yo lo sé; para la descarga de archivos, comprobando el tamaño del archivo es insignificante en términos de recursos. Resultado:. Usuario dispone de una barra de progreso determinada (y descargar páginas dinámicas gracias a rápidas gzip)

Otros consejos

Si la longitud del contenido se conoce de antemano, entonces sin duda lo prefieren por encima de enviar en trozos. Si hay medio de archivos estáticos en el sistema de archivos del disco local o en una base de datos, entonces cualquier lenguaje de programación auto-respetado y RDBMS proporciona maneras de conseguir la longitud del contenido de antemano. Usted debe hacer uso de ella.

Por otro lado, si la longitud del contenido es realmente impredecible de antemano (por ejemplo, cuando su intención es la de comprimir varios archivos juntos y enviarlo como uno), a continuación, enviarlo en trozos puede ser más rápido que el almacenamiento en búfer en la memoria o la escritura del servidor al sistema de archivos del disco local en primer lugar. Pero este hecho afecta negativamente la experiencia del usuario ya que el progreso de la descarga es desconocida. La impaciencia puede entonces abortar la descarga y moverse a lo largo.

Otra ventaja de saber de antemano la longitud del contenido es la capacidad de reanudar descargas. Veo en su historia post que su lenguaje de programación principal es Java; usted puede encontrar aquí un artículo con más información técnica básica y un ejemplo de Java Servlet, que lo hace.

Content-Length

La cabecera Content-Length determina la longitud de bytes del cuerpo de solicitud / respuesta. Si usted se olvida de especificar la cabecera Content-Length, servidores HTTP serán implícitamente agregar un encabezado Transfer-Encoding: chunked. La cabecera Content-Length y Transfer-Encoding no debe ser utilizado en conjunto. El receptor tiene ni idea de lo que la longitud del cuerpo es y no puede estimar el tiempo de terminación de descarga. Si añade una cabecera Content-Length, asegúrese de que corresponde a todo el cuerpo en bytes, si no es correcta, el comportamiento de los receptores no está definido.

La cabecera Content-Length no permitirá el streaming, pero es útil para grandes archivos binarios, en los que desee apoyar el contenido parcial de servir. Esto significa básicamente descargas reanudables, descargas pausadas, descargas parciales y descargas multitarjeta. Esto requiere el uso de una cabecera adicional llamado Range. Esta técnica se llama Byte servir .

Transfer-Encoding

El uso de Transfer-Encoding: chunked es lo que permite la transmisión dentro de una sola petición o respuesta. Esto significa que los datos se transmiten de una manera fragmentada, y no afecta a la representación del contenido.

Oficialmente un cliente HTTP está destinado a enviar una solicitud con un campo de cabecera TE que especifica qué tipo de transferencia de codificaciones que el cliente está dispuesto a aceptar. Esto no siempre se envía, sin embargo la mayoría de los servidores asumen que los clientes pueden procesar codificaciones chunked.

La codificación de transferencia chunked hace un mejor uso de conexiones TCP persistentes, que asume HTTP 1.1 para ser verdad por defecto.

Content-Encoding

También es posible comprimir los datos fragmentada o no fragmentada. Esto se realiza a través de prácticamente la cabecera Content-Encoding.

Tenga en cuenta que la Content-Length es igual a la longitud del cuerpo después de la Content-Encoding. Esto significa que si tiene gzip su respuesta, entonces el cálculo de la longitud sucede después de la compresión. Tendrá que ser capaz de cargar todo el cuerpo en la memoria si se quiere calcular la longitud (a no ser que tenga esa información en otro lugar).

Cuando se transmiten utilizando la codificación fragmentada, el algoritmo de compresión también debe ser compatible con el procesamiento en línea. Afortunadamente, compatible con la compresión gzip corriente. Creo que el contenido se comprime en primer lugar, y luego se corta en trozos. De esta manera, se reciben los trozos, se descomprimen para adquirir el contenido real. Si fuese al revés, que obtendrá la corriente comprimida, y luego descomprimir nos daría trozos. Lo cual no tiene sentido.

Una respuesta típica corriente comprimida puede tener estos encabezados:

Content-Type: text/html
Content-Encoding: gzip
Transfer-Encoding: chunked

Semánticamente el uso de Content-Encoding indica un "extremo a extremo" esquema de codificación, lo que significa sólo el cliente final o servidor final se supone que decodificar el contenido. La representación en el medio no se supone que debe decodificar el contenido.

Si desea permitir que los proxies en el medio para descifrar el contenido, el encabezado correcto a utilizar es de hecho la cabecera Transfer-Encoding. Si la petición HTTP poseía una cabecera TE: gzip chunked, entonces es legal para responder con Transfer-Encoding: gzip chunked.

Sin embargo, esto es muy poco compatible. Por lo que sólo debe utilizar Content-Encoding para su compresión en este momento.

fragmentada vs Store & Forward

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top