4. Codifiche di trasferimento
I nomi delle transfer coding sono usati per indicare una trasformazione di codifica che è stata, può essere, o potrebbe dover essere applicata a un payload del corpo al fine di garantire un "trasporto sicuro" attraverso la rete. Ciò differisce da una content coding in quanto la transfer coding è una proprietà del messaggio anziché una proprietà della rappresentazione che viene trasferita.
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 )
I parametri hanno la forma di un nome oppure di una coppia nome=valore.
transfer-parameter = token BWS "=" BWS ( token / quoted-string )
Tutti i nomi di transfer-coding non distinguono maiuscole e minuscole e dovrebbero essere registrati nel registro HTTP Transfer Coding, come definito nella Sezione 8.4. Sono usati nei campi di intestazione TE (Sezione 4.3) e Transfer-Encoding (Sezione 3.3.1).
4.1. Chunked transfer coding
La chunked transfer coding avvolge il payload del corpo per trasferirlo come una serie di chunk, ciascuno con il proprio indicatore di dimensione, seguiti da un trailer OPTIONAL contenente campi di intestazione. La chunked consente di trasferire flussi di contenuto di dimensione sconosciuta come sequenza di buffer delimitati da lunghezza, il che consente al mittente di mantenere la persistenza della connessione e al destinatario di sapere quando ha ricevuto l'intero messaggio.
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
Il campo chunk-size è una stringa di cifre esadecimali che indica la dimensione del chunk-data in ottetti. La chunked transfer coding è completa quando viene ricevuto un chunk con chunk-size pari a zero, eventualmente seguito da un trailer, e infine terminato da una riga vuota.
Un destinatario MUST essere in grado di analizzare e decodificare la chunked transfer coding.
4.1.1. Chunk extensions
La codifica chunked consente a ciascun chunk di includere zero o più chunk extension, immediatamente dopo il chunk-size, allo scopo di fornire metadati per-chunk (come una firma o un hash), informazioni di controllo a metà messaggio, oppure una randomizzazione della dimensione del corpo del messaggio.
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token / quoted-string
La codifica chunked è specifica per ciascuna connessione ed è probabile che venga rimossa o ricodificata da ciascun destinatario (inclusi gli intermediari) prima che qualsiasi applicazione di livello superiore abbia la possibilità di ispezionare le estensioni. Pertanto, l'uso delle chunk extension è generalmente limitato a servizi HTTP specializzati come il "long polling" (dove client e server possono avere aspettative condivise riguardo all'uso delle chunk extension) oppure al padding all'interno di una connessione protetta end-to-end.
Un destinatario MUST ignorare le chunk extension non riconosciute. Un server dovrebbe limitare la lunghezza totale delle chunk extension ricevute in una richiesta a un valore ragionevole per i servizi forniti, allo stesso modo in cui applica limiti di lunghezza e timeout per altre parti di un messaggio, e generare un'appropriata risposta 4xx (Client Error) se tale valore viene superato.
4.1.2. Parte trailer della chunked
Un trailer consente al mittente di includere campi aggiuntivi alla fine di un messaggio chunked, allo scopo di fornire metadati che potrebbero essere generati dinamicamente durante l'invio del corpo del messaggio, come un controllo di integrità del messaggio, una firma digitale o uno stato di post-elaborazione. I campi del trailer sono identici ai campi di intestazione, tranne per il fatto che vengono inviati in un trailer chunked anziché nella sezione di intestazione del messaggio.
trailer-part = *( header-field CRLF )
Un mittente MUST NOT generare un trailer che contenga un campo necessario per l'inquadratura del messaggio (ad es. Transfer-Encoding e Content-Length), l'instradamento (ad es. Host), i modificatori di richiesta (ad es. i controlli e i condizionali della Sezione 5 di [RFC7231]), l'autenticazione (ad es. vedere [RFC7235] e [RFC6265]), i dati di controllo della risposta (ad es. vedere la Sezione 7.1 di [RFC7231]), oppure la determinazione di come elaborare il payload (ad es. Content-Encoding, Content-Type, Content-Range e Trailer).
Quando viene ricevuto un messaggio chunked contenente un trailer non vuoto, il destinatario MAY elaborare i campi (a parte quelli vietati sopra) come se fossero stati aggiunti alla sezione di intestazione del messaggio. Un destinatario MUST ignorare (o considerare come errore) qualsiasi campo che sia vietato inviare in un trailer, poiché elaborarli come se fossero presenti nella sezione di intestazione potrebbe aggirare filtri di sicurezza esterni.
A meno che la richiesta non includa un campo di intestazione TE che indichi che "trailers" è accettabile, come descritto nella Sezione 4.3, un server SHOULD NOT generare campi di trailer che ritiene necessari perché lo user agent li riceva. Senza un TE contenente "trailers", il server dovrebbe presumere che i campi del trailer possano essere scartati silenziosamente lungo il percorso verso lo user agent. Questo requisito consente agli intermediari di inoltrare un messaggio de-chunked a un destinatario HTTP/1.0 senza memorizzare nel buffer l'intera risposta.
4.1.3. Decodifica della chunked
Un processo per decodificare la chunked transfer coding può essere rappresentato in pseudocodice come:
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. Codifiche di compressione
Le codifiche definite di seguito possono essere usate per comprimere il payload di un messaggio.
4.2.1. Compress coding
La codifica "compress" è una codifica Lempel-Ziv-Welch (LZW) adattiva [Welch] che è comunemente prodotta dal programma UNIX di compressione dei file "compress". Un destinatario SHOULD considerare "x-compress" equivalente a "compress".
4.2.2. Deflate coding
La codifica "deflate" è un formato di dati "zlib" [RFC1950] contenente un flusso di dati compresso "deflate" [RFC1951] che usa una combinazione dell'algoritmo di compressione Lempel-Ziv (LZ77) e della codifica di Huffman.
Nota: alcune implementazioni non conformi inviano i dati compressi "deflate" senza il wrapper zlib.
4.2.3. Gzip coding
La codifica "gzip" è una codifica LZ77 con un Cyclic Redundancy Check (CRC) a 32 bit che è comunemente prodotta dal programma di compressione di file gzip [RFC1952]. Un destinatario SHOULD considerare "x-gzip" equivalente a "gzip".
4.3. TE
Il campo di intestazione "TE" in una richiesta indica quali transfer coding, oltre a chunked, il client è disposto ad accettare in risposta, e se il client è disposto o meno ad accettare campi di trailer in una chunked transfer coding.
Il field-value di TE consiste in un elenco separato da virgole di nomi di transfer coding, ciascuno dei quali consente parametri opzionali (come descritto nella Sezione 4), e/o la parola chiave "trailers". Un client MUST NOT inviare il nome della chunked transfer coding in TE; chunked è sempre accettabile per i destinatari 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") ] )
Di seguito sono riportati tre esempi di uso di TE.
TE: deflate
TE:
TE: trailers, deflate;q=0.5
La presenza della parola chiave "trailers" indica che il client è disposto ad accettare campi di trailer in una chunked transfer coding, come definito nella Sezione 4.1.2, per conto proprio e di qualsiasi client a valle. Per le richieste provenienti da un intermediario, ciò implica che: (a) tutti i client a valle siano disposti ad accettare campi di trailer nella risposta inoltrata; oppure (b) l'intermediario tenterà di memorizzare nel buffer la risposta per conto dei destinatari a valle. Si noti che HTTP/1.1 non definisce alcun mezzo per limitare la dimensione di una risposta chunked tale da poter garantire a un intermediario di memorizzare nel buffer l'intera risposta.
Quando più transfer coding sono accettabili, il client MAY ordinare le codifiche per preferenza usando un parametro "q" che non distingue maiuscole e minuscole (simile ai qvalue usati nei campi di negoziazione del contenuto, Sezione 5.3.1 di [RFC7231]). Il valore di ordinamento è un numero reale nell'intervallo da 0 a 1, dove 0.001 è il meno preferito e 1 è il più preferito; un valore di 0 significa "non accettabile".
Se il field-value di TE è vuoto o se non è presente alcun campo TE, l'unica transfer coding accettabile è chunked. Un messaggio senza transfer coding è sempre accettabile.
Poiché il campo di intestazione TE si applica solo alla connessione immediata, un mittente di TE MUST inviare anche un'opzione di connessione "TE" all'interno del campo di intestazione Connection (Sezione 6.1) per impedire che il campo TE venga inoltrato da intermediari che non supportano la sua semantica.
4.4. Trailer
Quando un messaggio include un corpo del messaggio codificato con la chunked transfer coding e il mittente desidera inviare metadati sotto forma di campi di trailer alla fine del messaggio, il mittente SHOULD generare un campo di intestazione Trailer prima del corpo del messaggio per indicare quali campi saranno presenti nei trailer. Ciò consente al destinatario di prepararsi a ricevere quei metadati prima di iniziare a elaborare il corpo, il che è utile se il messaggio viene trasmesso in streaming e il destinatario desidera confermare al volo un controllo di integrità.
Trailer = 1#field-name