Aller au contenu principal

4. Transfer Codings

Les noms de codage de transfert servent à indiquer une transformation d'encodage qui a été, peut être, ou pourrait devoir être appliquée à un corps de charge utile afin d'assurer un « transport sûr » à travers le réseau. Cela diffère d'un codage de contenu en ce que le codage de transfert est une propriété du message plutôt qu'une propriété de la représentation qui est transférée.

transfer-coding    = "chunked" ; Section 4.1
/ "compress" ; Section 4.2.1
/ "deflate" ; Section 4.2.2
/ "gzip" ; Section 4.2.3
/ transfer-extension
transfer-extension = token *( OWS ";" OWS transfer-parameter )

Les paramètres se présentent sous la forme d'un nom ou d'une paire nom=valeur.

transfer-parameter = token BWS "=" BWS ( token / quoted-string )

Tous les noms de codage de transfert sont insensibles à la casse et devraient être enregistrés dans le registre HTTP Transfer Coding, comme défini à la Section 8.4. Ils sont utilisés dans les champs d'en-tête TE (Section 4.3) et Transfer-Encoding (Section 3.3.1).

4.1. Codage de transfert chunked​

Le codage de transfert chunked enveloppe le corps de charge utile afin de le transférer sous forme d'une série de chunks, chacun doté de son propre indicateur de taille, suivis d'un trailer OPTIONAL contenant des champs d'en-tête. Chunked permet de transférer des flux de contenu de taille inconnue sous forme d'une séquence de tampons délimités par leur longueur, ce qui permet à l'expéditeur de préserver la persistance de la connexion et au destinataire de savoir quand il a reçu le message entier.

chunked-body   = *chunk
last-chunk
trailer-part
CRLF

chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = 1*HEXDIG
last-chunk = 1*("0") [ chunk-ext ] CRLF

chunk-data = 1*OCTET ; a sequence of chunk-size octets

Le champ chunk-size est une chaîne de chiffres hexadécimaux indiquant la taille des chunk-data en octets. Le codage de transfert chunked est complet lorsqu'un chunk dont la chunk-size est nulle est reçu, éventuellement suivi d'un trailer, et enfin terminé par une ligne vide.

Un destinataire MUST être capable d'analyser et de décoder le codage de transfert chunked.

4.1.1. Extensions de chunk​

Le codage chunked permet à chaque chunk d'inclure zéro ou plusieurs extensions de chunk, immédiatement après la chunk-size, afin de fournir des métadonnées propres à chaque chunk (telles qu'une signature ou un hachage), des informations de contrôle au milieu du message, ou une randomisation de la taille du corps du message.

chunk-ext      = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )

chunk-ext-name = token
chunk-ext-val = token / quoted-string

Le codage chunked est propre à chaque connexion et est susceptible d'être supprimé ou recodé par chaque destinataire (y compris les intermédiaires) avant qu'une application de niveau supérieur n'ait la possibilité d'examiner les extensions. Par conséquent, l'usage des extensions de chunk est généralement limité à des services HTTP spécialisés tels que le « long polling » (où client et serveur peuvent partager des attentes communes quant à l'usage des extensions de chunk) ou au remplissage à l'intérieur d'une connexion sécurisée de bout en bout.

Un destinataire MUST ignorer les extensions de chunk non reconnues. Un serveur devrait limiter la longueur totale des extensions de chunk reçues dans une requête à une quantité raisonnable pour les services fournis, de la même manière qu'il applique des limitations de longueur et des délais d'attente pour d'autres parties d'un message, et générer une réponse 4xx (Client Error) appropriée si cette quantité est dépassée.

4.1.2. Partie trailer du chunked​

Un trailer permet à l'expéditeur d'inclure des champs supplémentaires à la fin d'un message chunked afin de fournir des métadonnées qui peuvent être générées dynamiquement pendant l'envoi du corps du message, telles qu'un contrôle d'intégrité de message, une signature numérique, ou un statut de post-traitement. Les champs de trailer sont identiques aux champs d'en-tête, à ceci près qu'ils sont envoyés dans un trailer chunked au lieu de la section d'en-tête du message.

trailer-part   = *( header-field CRLF )

Un expéditeur MUST NOT générer de trailer contenant un champ nécessaire au cadrage du message (par exemple Transfer-Encoding et Content-Length), au routage (par exemple Host), aux modificateurs de requête (par exemple les contrôles et conditions de la Section 5 de [RFC7231]), à l'authentification (par exemple voir [RFC7235] et [RFC6265]), aux données de contrôle de réponse (par exemple voir la Section 7.1 de [RFC7231]), ou à la détermination de la façon de traiter la charge utile (par exemple Content-Encoding, Content-Type, Content-Range et Trailer).

Lorsqu'un message chunked contenant un trailer non vide est reçu, le destinataire MAY traiter les champs (à l'exception de ceux interdits ci-dessus) comme s'ils étaient ajoutés à la section d'en-tête du message. Un destinataire MUST ignorer (ou considérer comme une erreur) tout champ dont l'envoi dans un trailer est interdit, car les traiter comme s'ils étaient présents dans la section d'en-tête pourrait contourner des filtres de sécurité externes.

Sauf si la requête comprend un champ d'en-tête TE indiquant que « trailers » est acceptable, comme décrit à la Section 4.3, un serveur SHOULD NOT générer de champs de trailer qu'il estime nécessaires à la réception par l'agent utilisateur. Sans un TE contenant « trailers », le serveur devrait supposer que les champs de trailer peuvent être silencieusement écartés le long du chemin vers l'agent utilisateur. Cette exigence permet aux intermédiaires de transférer un message dé-chunké à un destinataire HTTP/1.0 sans mettre en mémoire tampon toute la réponse.

4.1.3. Décodage du chunked​

Un processus de décodage du codage de transfert chunked peut être représenté en pseudo-code comme suit :

length := 0
read chunk-size, chunk-ext (if any), and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to decoded-body
length := length + chunk-size
read chunk-size, chunk-ext (if any), and CRLF
}
read trailer field
while (trailer field is not empty) {
if (trailer field is allowed to be sent in a trailer) {
append trailer field to existing header fields
}
read trailer-field
}
Content-Length := length
Remove "chunked" from Transfer-Encoding
Remove Trailer from existing header fields

4.2. Codages de compression​

Les codages définis ci-dessous peuvent être utilisés pour compresser la charge utile d'un message.

4.2.1. Codage compress​

Le codage « compress » est un codage adaptatif Lempel-Ziv-Welch (LZW) [Welch] qui est communément produit par le programme de compression de fichiers UNIX « compress ». Un destinataire SHOULD considérer « x-compress » comme équivalent à « compress ».

4.2.2. Codage deflate​

Le codage « deflate » est un format de données « zlib » [RFC1950] contenant un flux de données compressées « deflate » [RFC1951] qui utilise une combinaison de l'algorithme de compression Lempel-Ziv (LZ77) et du codage de Huffman.

Note : certaines implémentations non conformes envoient les données compressées « deflate » sans l'enveloppe zlib.

4.2.3. Codage gzip​

Le codage « gzip » est un codage LZ77 avec un contrôle de redondance cyclique (CRC) de 32 bits qui est communément produit par le programme de compression de fichiers gzip [RFC1952]. Un destinataire SHOULD considérer « x-gzip » comme équivalent à « gzip ».

4.3. TE​

Le champ d'en-tête « TE » d'une requête indique quels codages de transfert, autres que chunked, le client est disposé à accepter dans la réponse, et si le client est disposé ou non à accepter des champs de trailer dans un codage de transfert chunked.

La field-value de TE se compose d'une liste séparée par des virgules de noms de codage de transfert, chacun autorisant des paramètres facultatifs (comme décrit à la Section 4), et/ou du mot-clé « trailers ». Un client MUST NOT envoyer le nom du codage de transfert chunked dans TE ; chunked est toujours acceptable pour les destinataires HTTP/1.1.

TE        = #t-codings
t-codings = "trailers" / ( transfer-coding [ t-ranking ] )
t-ranking = OWS ";" OWS "q=" rank
rank = ( "0" [ "." 0*3DIGIT ] )
/ ( "1" [ "." 0*3("0") ] )

Trois exemples d'utilisation de TE sont donnés ci-dessous.

TE: deflate
TE:
TE: trailers, deflate;q=0.5

La présence du mot-clé « trailers » indique que le client est disposé à accepter des champs de trailer dans un codage de transfert chunked, comme défini à la Section 4.1.2, pour son propre compte et pour celui de tout client en aval. Pour les requêtes provenant d'un intermédiaire, cela implique soit (a) que tous les clients en aval sont disposés à accepter des champs de trailer dans la réponse transférée, soit (b) que l'intermédiaire tentera de mettre en mémoire tampon la réponse pour le compte des destinataires en aval. Notez que HTTP/1.1 ne définit aucun moyen de limiter la taille d'une réponse chunked de sorte qu'un intermédiaire puisse être assuré de mettre en mémoire tampon la réponse entière.

Lorsque plusieurs codages de transfert sont acceptables, le client MAY classer les codages par préférence à l'aide d'un paramètre « q » insensible à la casse (semblable aux qvalues utilisées dans les champs de négociation de contenu, Section 5.3.1 de [RFC7231]). La valeur de rang est un nombre réel compris entre 0 et 1, où 0.001 est le moins préféré et 1 le plus préféré ; une valeur de 0 signifie « non acceptable ».

Si la field-value de TE est vide ou si aucun champ TE n'est présent, le seul codage de transfert acceptable est chunked. Un message sans codage de transfert est toujours acceptable.

Comme le champ d'en-tête TE ne s'applique qu'à la connexion immédiate, un expéditeur de TE MUST également envoyer une option de connexion « TE » dans le champ d'en-tête Connection (Section 6.1) afin d'empêcher le champ TE d'être transféré par des intermédiaires qui ne prennent pas en charge sa sémantique.

4.4. Trailer​

Lorsqu'un message comprend un corps de message encodé avec le codage de transfert chunked et que l'expéditeur souhaite envoyer des métadonnées sous forme de champs de trailer à la fin du message, l'expéditeur SHOULD générer un champ d'en-tête Trailer avant le corps du message pour indiquer quels champs seront présents dans les trailers. Cela permet au destinataire de se préparer à la réception de ces métadonnées avant de commencer à traiter le corps, ce qui est utile si le message est diffusé en flux et que le destinataire souhaite confirmer à la volée un contrôle d'intégrité.

Trailer = 1#field-name