http - content - Codificación de transferencia: gzip vs. Codificación de contenido: gzip
header gzip (2)
Citando a Roy T. Fielding , uno de los autores de RFC 2616:
cambiar la codificación de contenido sobre la marcha de manera inconsistente (ni "nunca" ni "siempre") hace que sea imposible que las solicitudes posteriores con respecto a ese contenido (por ejemplo, PUT o GET condicional) se manejen correctamente. Esto es, por supuesto, por qué la codificación de contenido on-the-fly es una idea estúpida, y por qué agregué Transfer-Encoding a HTTP como la forma correcta de hacer una codificación sobre la marcha sin cambiar el recurso.
Fuente: https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31
En otras palabras: no haga sobre-la -codificación de contenido sobre la marcha , ¡use la codificación de transferencia en su lugar!
Editar: Es decir, a menos que quieras servir contenido comprimido a clientes que solo entienden Content-Encoding . Lo cual, 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 los mencionados por Fielding y otros, por ejemplo, cuando se trata de proxies de almacenamiento en caché.
¿Cuál es el estado actual de las cosas cuando se trata de hacer o no?
Transfer-Encoding: gzip
o una
Content-Encoding: gzip
cuando quiero permitir que los clientes, por ejemplo, con ancho de banda limitado, indiquen que están dispuestos a aceptar una respuesta comprimida y el servidor tiene la última palabra sobre si comprimir o no .
Este último es, por ejemplo, el mod_deflate de Apache y el IIS, si dejas que se encargue de la compresión. Dependiendo del tamaño del contenido que se comprimirá, hará la Transfer-Encoding: chunked
adicional Transfer-Encoding: chunked
.
También incluirá un Vary: Accept-Encoding
, que ya alude al problema. Content-Encoding
parece ser parte de la entidad, por lo que cambiar Content-Encoding
equivale a un cambio de la entidad, es decir, un encabezado Accept-Encoding
diferente significa, por ejemplo, que un caché no puede usar su versión en caché de la entidad que de otro modo sería idéntica.
¿Hay una respuesta definitiva al respecto que me he perdido (y que no está enterrada dentro de un mensaje en un largo hilo en algún grupo de noticias de apache)?
Mi impresión actual es:
- La codificación de transferencia sería, de hecho, la manera correcta de hacer lo que se hace principalmente con Content-Encoding por implementaciones de servidor y cliente existentes
- Content-Encoding, debido a sus implicaciones semánticas, conlleva un par de problemas (¿qué debe hacer el servidor con el
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 lo hacen
Así que estoy asumiendo que el camino correcto sería una Transfer-Encoding: gzip
(o, si también hechizo el cuerpo, se convertiría Transfer-Encoding: gzip, chunked
). Y no hay ninguna razón para tocar Vary
o ETag
o cualquier otro encabezado en ese caso, ya que es una cuestión de nivel de transporte.
Por ahora no me importa demasiado el ''salto a salto'' de Transfer-Encoding
, algo en lo que otros parecen estar preocupados en primer lugar, porque los proxies pueden descomprimir y enviar sin comprimir al cliente. Sin embargo, los proxies también podrían reenviarlo como está (comprimido), si la solicitud original tiene el encabezado Accept-Encoding
adecuado, que en el caso de todos los navegadores que conozco se da por hecho.
Por cierto, este problema tiene al menos una década de antigüedad, véase, por ejemplo, https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .
Cualquier aclaración sobre esto será apreciada. Tanto en términos de lo que se considera que cumple con los estándares como de lo que se considera práctico. Por ejemplo, las bibliotecas de cliente HTTP que solo admiten una "codificación de contenido" transparente serían un argumento en contra de lo práctico.
El uso correcto , como se define en RFC 2616 y realmente implementado en la naturaleza, es para que el cliente envíe un encabezado de solicitud de Accept-Encoding
(el cliente puede especificar múltiples codificaciones). Entonces, el servidor puede, y solo entonces, codificar la respuesta de acuerdo con las codificaciones compatibles del cliente (si los datos del archivo aún no están almacenados en esa codificación), indique en el encabezado de respuesta de Content-Encoding
qué codificación se está utilizando. El cliente puede entonces leer los datos del socket en función de la Transfer-Encoding
(es decir, chunked
) y luego decodificarla en función de la Content-Encoding
(es decir, gzip
).
Entonces, en su caso, el cliente enviaría un encabezado de solicitud de Accept-Encoding: gzip
, y luego el servidor podría decidir comprimir (si no es que ya lo hizo) y enviar un Content-Encoding: gzip
y, opcionalmente Transfer-Encoding: chunked
respuesta Transfer-Encoding: chunked
.
Y sí, el encabezado Transfer-Encoding
se puede usar en solicitudes, pero solo para HTTP 1.1, que requiere que las implementaciones de cliente y servidor admitan la codificación chunked
en ambas direcciones.
ETag
identifica de manera única los datos de recursos en el servidor, no los datos que realmente se transmiten. Si un recurso de URL determinado cambia su valor de ETag
, significa que los datos del lado del servidor para ese recurso han cambiado.