¿Cuál es el estado actual de las cosas cuando se trata de si hacer
Transfer-Encoding: gzip
o un
Content-Encoding: gzip
cuando quiero permitir que los clientes, por ejemplo, con un ancho de banda limitado, indiquen su voluntad de aceptar una respuesta comprimida y el servidor tenga la última palabra sobre si comprimir o no .
Esto último es lo que hacen, por ejemplo, mod_deflate e IIS de Apache, si deja que se encargue de la compresión. Dependiendo del tamaño del contenido a comprimir, hará lo adicional Transfer-Encoding: chunked
.
También incluirá un Vary: Accept-Encoding
, que ya insinúa el problema. Content-Encoding
parece ser parte de la entidad, por lo que cambiar las Content-Encoding
cantidades a un cambio de la entidad, es decir, un Accept-Encoding
encabezado diferente significa, por ejemplo, que un caché no puede usar su versión en caché de la entidad por lo demás idéntica.
¿Hay una respuesta definitiva a esto que me he perdido (y que no está enterrada dentro de un mensaje en un hilo largo en algún grupo de noticias de Apache)?
Mi impresión actual es:
- Transfer-Encoding sería, de hecho, la forma correcta de hacer lo que se hace principalmente con Content-Encoding mediante implementaciones de servidor y cliente existentes
- Content-Encoding, debido a sus implicaciones semánticas, conlleva un par de problemas (¿qué debe hacer el servidor
ETag
cuando comprime de forma transparente una respuesta?) - La razón es chicken'n'egg: los navegadores no lo admiten porque los servidores no lo hacen porque los navegadores no
Así que supongo que la forma correcta sería un Transfer-Encoding: gzip
(o, si además trozo el cuerpo, se convertiría Transfer-Encoding: gzip, chunked
). Y no hay razón para tocar Vary
o ETag
cualquier otro encabezado en ese caso, ya que es una cosa a nivel de transporte.
Por ahora no me importa demasiado el 'salto a salto' Transfer-Encoding
, algo que a los demás parece preocuparles en primer lugar, porque los proxies pueden descomprimir y reenviar sin comprimir al cliente. Sin embargo, los proxies podrían reenviarlo tal como está (comprimido), si la solicitud original tiene el Accept-Encoding
encabezado adecuado , que en el caso de todos los navegadores que conozco es un hecho.
Por cierto, este problema tiene al menos una década, consulte, por ejemplo, https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .
Se agradecerá cualquier aclaración al respecto. Tanto en términos de lo que se considera compatible con los estándares como de lo que se considera práctico. Por ejemplo, las bibliotecas cliente HTTP que solo admitan una "codificación de contenido" transparente serían un argumento en contra de la practicidad.
fuente
Transfer-Encoding:gzip
, aunque la línea de comandos curl sí. Para estar seguro, envíe ambos, a menos que esté combinando chunked y gzip.Respuestas:
Citando a Roy T. Fielding , uno de los autores de RFC 2616:
Fuente: https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31
En otras palabras: no realice la codificación de contenido sobre la marcha , ¡use la codificación de transferencia en su lugar!
Editar: es decir, a menos que desee ofrecer contenido comprimido con gzip a clientes que solo entienden la codificación de contenido . Que, lamentablemente, parece ser la mayoría de ellos. Pero tenga en cuenta que abandona los dominios de la especificación y puede encontrarse con problemas como el mencionado por Fielding y otros, por ejemplo, cuando se trata de caché de proxies.
fuente
TE: gzip
. Y luego su servidor debería seguir la ruta de Codificación de Transferencia. Si el cliente solo lo diceAccept-Encoding: gzip
, debe hacerlo de laContent-Encoding
manera. Si el cliente no especifica ninguno en su solicitud, el servidor no debe hacer gzip en absoluto.El uso correcto , como se define en RFC 2616 y realmente implementado en la naturaleza, es que el cliente envíe un
Accept-Encoding
encabezado de solicitud (el cliente puede especificar múltiples codificaciones). El servidor puede entonces, y solo entonces, codificar la respuesta de acuerdo con las codificaciones admitidas por el cliente (si los datos del archivo aún no están almacenados en esa codificación), indicar en elContent-Encoding
encabezado de respuesta qué codificación se está utilizando. A continuación, el cliente puede leer los datos del socket según elTransfer-Encoding
(es decir,chunked
) y luego decodificarlos según elContent-Encoding
(es decir:)gzip
.Entonces, en su caso, el cliente enviaría un
Accept-Encoding: gzip
encabezado de solicitud, y luego el servidor puede decidir comprimir (si aún no lo ha hecho) y enviar un encabezado de respuestaContent-Encoding: gzip
opcionalTransfer-Encoding: chunked
.Y sí, el
Transfer-Encoding
encabezado se puede usar en solicitudes, pero solo para HTTP 1.1, que requiere que tanto las implementaciones de cliente como de servidor admitan lachunked
codificación en ambas direcciones.ETag
identifica de forma única los datos de recursos en el servidor, no los datos que se transmiten realmente. Si un recurso de URL determinado cambia suETag
valor, significa que los datos del lado del servidor para ese recurso han cambiado.fuente
Content-Encoding
requiere diferenteETag
Esto es por cierto de lo que se trata el error mod_deflate al que me refiero en mi respuesta. Me hace preguntarme por qué este detalle a nivel de aplicación está en el estándar HTTP en primer lugar.Transfer-Encoding
Sin embargo, cuando se utiliza un ajuste de nivel de transporte, no es necesario cambiar elETag
. Excepto que nadie ha implementado Transfer-Enc.Content-Encoding
frenteTransfer-Encoding
. Sí, gzip debería ser una propiedad de la transferencia de un recurso, si se realiza sobre la marcha. Por otro lado, si el recurso se almacena comprimido en el servidor, debería ser una propiedad del contenido del recurso en su lugar, si se envía tal cual. Pero lo que debería ser y lo que realmente es no siempre son lo mismo.