web-dev-qa-db-fra.com

Transfert-codage: gzip contre contenu-codage: gzip

Quel est l'état actuel des choses quand il s'agit de faire ou non

Transfer-Encoding: gzip

ou un

Content-Encoding: gzip

quand je veux autoriser des clients avec par exemple une bande passante limitée à indique sa volonté d'accepter une réponse comprimée et le serveur a le dernier mot si compresser .

Ce dernier est ce que par exemple. Apache's mod_deflate et IIS faire, si vous le laissez prendre en charge la compression. Selon la taille du contenu à compresser, il effectuera le Transfer-Encoding: chunked.

Il comprendra également un Vary: Accept-Encoding, qui fait déjà allusion au problème. Content-Encoding semble faire partie de l'entité, donc changer le Content-Encoding _ équivaut à un changement d’entité, c.-à-d. un autre Accept-Encoding en-tête signifie par exemple un cache ne peut pas utiliser sa version en cache de l'entité identique par ailleurs.

Existe-t-il une réponse définitive à cette question que j'ai manquée (et qui n'est pas enfouie dans un message dans un long fil de discussion dans un groupe de discussion Apache)?

Mon impression actuelle est:

  • Le codage de transfert serait en fait le bon moyen de faire ce qui est principalement fait avec le codage de contenu avec les implémentations existantes du serveur et du client.
  • Le codage de contenu, en raison de ses implications sémantiques, pose quelques problèmes (que doit faire le serveur pour le ETag quand il compresse une réponse de manière transparente?)
  • Chicken'n'Egg: les navigateurs ne le supportent pas, pas les serveurs parce que les navigateurs ne le font pas

Je suppose donc que le bon chemin serait un Transfer-Encoding: gzip _ (ou, si je coupe en plus le corps, il deviendraTransfer-Encoding: gzip, chunked). Et aucune raison de toucher Vary ou ETag ou tout autre en-tête dans ce cas, car il s’agit d’une opération au niveau du transport.

Pour le moment, je me fiche bien du "sauts par sauts" de Transfer-Encoding, quelque chose qui préoccupe d’abord les autres, car les mandataires risquent de se décompresser et de les transmettre non compressés au client. Cependant, les mandataires pourraient tout aussi bien le transmettre tel quel (compressé), si la requête initiale a le bon fichier Accept-Encoding _ en-tête, ce qui est le cas pour tous les navigateurs que je connais.

Btw, cette question est au moins une décennie, voir par exemple. https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .

Toute clarification à ce sujet sera appréciée. Tant en ce qui concerne ce qui est considéré conforme aux normes et ce qui est considéré comme pratique. Par exemple, les bibliothèques client HTTP prenant uniquement en charge un "encodage de contenu" transparent constitueraient un argument contre la fonctionnalité.

88
Eugene Beresovsky

Citant Roy T. Fielding , l’un des auteurs du RFC 2616:

modifier le codage du contenu à la volée de manière incohérente (ni "jamais" ni "toujours") empêche de traiter correctement les requêtes ultérieures concernant ce contenu (par exemple, PUT ou GET conditionnel). C’est bien sûr pourquoi Le codage de contenu à la volée est une idée stupide et c'est pourquoi j'ai ajouté le codage de transfert à HTTP comme moyen approprié de procéder à un codage à la volée sans changer la ressource.

Source: https://issues.Apache.org/bugzilla/show_bug.cgi?id=39727#c31

En d'autres termes: ne faites pas à la volée Content-Encoding, utilisez plutôt Transfer-Encoding!

Éditez: C'est-à-dire que , sauf si vous souhaitez diffuser du contenu gzippé à des clients ne comprenant que le codage de contenu . Ce qui, malheureusement, semble être la plupart d'entre eux. Mais sachez que vous quittez le domaine de la spécification et pourriez vous heurter à des problèmes tels que celui mentionné par Fielding, entre autres, par exemple. lors de la mise en cache des mandataires sont impliqués.

33
Eugene Beresovsky

L’utilisation correcte, définie dans la RFC 2616 et implémentée dans la nature, permet au client d’envoyer un Accept-Encoding en-tête de demande (le client peut spécifier plusieurs codages). Le serveur peut alors, et seulement ensuite, coder la réponse en fonction des codages pris en charge par le client (si les données du fichier ne sont pas déjà stockées dans ce codage), indiquer dans le Content-Encoding _en-tête de la réponse indiquant le codage utilisé. Le client peut alors lire les données du socket en fonction du Transfer-Encoding (c'est-à-dire chunked) puis décodez-le en fonction du Content-Encoding (c'est-à-dire: gzip).

Donc, dans votre cas, le client enverrait un Accept-Encoding: gzip en-tête de requête, puis le serveur peut décider de compresser (si ce n’est déjà fait) et d’envoyer un Content-Encoding: gzip et éventuellement Transfer-Encoding: chunked en-tête de réponse.

Et oui, le Transfer-Encoding header peut être utilisé dans les requêtes, mais uniquement pour HTTP 1.1, qui nécessite que les implémentations client et serveur prennent en charge le codage chunked dans les deux sens.

ETag identifie de manière unique les données de la ressource sur le serveur, pas les données en cours de transmission. Si une ressource URL donnée change sa valeur ETag, cela signifie que les données côté serveur de cette ressource ont été modifiées.

26
Remy Lebeau