3. Capsule
Un meccanismo per estendere HTTP consiste nell'introdurre nuovi token di upgrade HTTP; vedere la sezione 16.7 di [HTTP]. In HTTP/1.x, questi token vengono utilizzati tramite il meccanismo Upgrade; vedere la sezione 7.8 di [HTTP]. In HTTP/2 e HTTP/3, questi token vengono utilizzati tramite il meccanismo Extended CONNECT; vedere [EXT-CONNECT2] e [EXT-CONNECT3].
Questa specifica introduce il protocollo Capsule. Il protocollo Capsule è una sequenza di tuple tipo-lunghezza-valore che le definizioni di nuovi token di upgrade HTTP possono scegliere di utilizzare. Consente agli endpoint di comunicare in modo affidabile informazioni relative alle richieste end-to-end sui flussi di richiesta HTTP, anche in presenza di intermediari HTTP. Il protocollo Capsule può essere utilizzato per scambiare datagrammi HTTP, il che è necessario quando HTTP viene eseguito su un trasporto che non supporta il frame QUIC DATAGRAM. Il protocollo Capsule può anche essere utilizzato per comunicare messaggi di controllo affidabili e bidirezionali associati a un protocollo basato su datagrammi anche quando i datagrammi HTTP/3 sono in uso.
3.1. Flussi di dati HTTP (HTTP Data Streams)
Questa specifica definisce il "flusso di dati" (data stream) di una richiesta HTTP come il flusso bidirezionale di byte che segue la sezione di intestazione del messaggio di richiesta e il messaggio di risposta finale che è either riuscito (cioè 2xx) o aggiornato (cioè 101).
In HTTP/1.x, il flusso di dati consiste di tutti i byte sulla connessione che seguono la riga vuota che conclude la sezione di intestazione della richiesta o la sezione di intestazione della risposta finale. Di conseguenza, solo l'ultima richiesta HTTP su una connessione HTTP/1.x può avviare il protocollo Capsule.
In HTTP/2 e HTTP/3, il flusso di dati di una data richiesta HTTP consiste di tutti i byte inviati nei frame DATA con l'ID di flusso corrispondente.
Il concetto di flusso di dati è particolarmente rilevante per metodi come CONNECT, dove non c'è contenuto del messaggio HTTP dopo le intestazioni.
I flussi di dati possono essere prioritizzati utilizzando qualsiasi mezzo adatto alla prioritizzazione di flussi o richieste. Ad esempio, vedere la sezione 11 di [PRIORITY].
I flussi di dati sono soggetti ai meccanismi di controllo del flusso dei livelli sottostanti; gli esempi includono il controllo del flusso del flusso HTTP/2, il controllo del flusso della connessione HTTP/2 e il controllo del flusso TCP.
3.2. Il protocollo Capsule (The Capsule Protocol)
Le definizioni di nuovi token di upgrade HTTP possono dichiarare che il flusso di dati della richiesta associata utilizza il protocollo Capsule. Se lo fanno, il contenuto del flusso di dati della richiesta associata utilizza il seguente formato:
Capsule Protocol {
Capsule (..) ...,
}
Figura 2: Formato del flusso del protocollo Capsule
Capsule {
Capsule Type (i),
Capsule Length (i),
Capsule Value (..),
}
Figura 3: Formato della capsula
Capsule Type: Un intero a lunghezza variabile che indica il tipo della capsula. Un registro IANA viene utilizzato per gestire l'assegnazione dei tipi di capsule; vedere la sezione 5.4.
Capsule Length: La lunghezza, in byte, del campo Capsule Value che segue questo campo, codificata come un intero a lunghezza variabile. Si noti che questo campo può avere un valore pari a zero.
Capsule Value: Il payload di questa capsula. La sua semantica è determinata dal valore del campo Capsule Type.
Un intermediario può identificare l'uso del protocollo Capsule attraverso la presenza del campo di intestazione Capsule-Protocol (sezione 3.4) o comprendendo il token di upgrade HTTP scelto.
Poiché nuovi protocolli o estensioni potrebbero definire nuovi tipi di capsule, gli intermediari che desiderano consentire l'estensibilità futura dovrebbero (SHOULD) inoltrare le capsule senza modifiche a meno che la definizione del tipo di capsula in uso non specifichi un'elaborazione intermedia aggiuntiva. Un tale tipo di capsula è la capsula DATAGRAM; vedere la sezione 3.5. In particolare, gli intermediari dovrebbero (SHOULD) inoltrare le capsule con un tipo di capsula sconosciuto senza modifiche.
Gli endpoint che ricevono una capsula con un tipo di capsula sconosciuto devono (MUST) scartare silenziosamente quella capsula e saltarla per analizzare la capsula successiva.
In virtù della definizione del flusso di dati:
-
Il protocollo Capsule non è in uso a meno che la risposta non includa un codice di stato 2xx (Riuscito) o 101 (Cambio di protocolli).
-
Quando il protocollo Capsule è in uso, la richiesta HTTP e la risposta associate non trasportano contenuto HTTP. Un'estensione futura può (MAY) definire un nuovo tipo di capsula per trasportare contenuto HTTP.
Il protocollo Capsule si applica solo alle definizioni di nuovi token di upgrade HTTP; quindi, in HTTP/2 e HTTP/3, può essere utilizzato solo con il metodo CONNECT. Pertanto, una volta che entrambi gli endpoint accettano di utilizzare il protocollo Capsule, i requisiti di utilizzo dei frame del flusso cambiano come specificato nella sezione 8.5 di [HTTP/2] e nella sezione 4.4 di [HTTP/3].
Il protocollo Capsule non deve (MUST NOT) essere utilizzato con messaggi che contengono i campi di intestazione Content-Length, Content-Type o Transfer-Encoding. Inoltre, i codici di stato HTTP 204 (No Content), 205 (Reset Content) e 206 (Partial Content) non devono (MUST NOT) essere inviati su risposte che utilizzano il protocollo Capsule. Un ricevitore che osserva una violazione di questi requisiti deve (MUST) trattare il messaggio HTTP come mal formato.
Durante l'elaborazione delle capsule, un ricevitore potrebbe essere tentato di accumulare l'intera lunghezza del campo Capsule Value nel flusso di dati prima di gestirlo. Questo approccio dovrebbe (SHOULD) essere evitato perché può consumare il controllo del flusso nei livelli sottostanti, e ciò potrebbe portare a deadlock se i dati della capsula esauriscono la finestra di controllo del flusso.
3.3. Gestione degli errori (Error Handling)
Quando un ricevitore incontra un errore durante l'elaborazione del protocollo Capsule, il ricevitore deve (MUST) trattarlo come se avesse ricevuto un messaggio HTTP mal formato o incompleto. Per HTTP/3, la gestione dei messaggi mal formati è descritta nella sezione 4.1.2 di [HTTP/3]. Per HTTP/2, la gestione dei messaggi mal formati è descritta nella sezione 8.1.1 di [HTTP/2]. Per HTTP/1.x, la gestione dei messaggi incompleti è descritta nella sezione 8 di [HTTP/1.1].
Il payload di ciascuna capsula deve (MUST) contenere esattamente i campi identificati nella sua descrizione. Un payload di capsula che contiene byte aggiuntivi dopo i campi identificati o un payload di capsula che termina prima della fine dei campi identificati deve (MUST) essere trattato come se fosse un messaggio mal formato o incompleto. In particolare, le codifiche di lunghezza ridondanti devono (MUST) essere verificate per essere auto-coerenti.
Se il lato di ricezione di un flusso che trasporta capsule viene terminato in modo pulito (ad esempio, in HTTP/3 questo è definito come la ricezione di un frame QUIC STREAM con il bit FIN impostato) e l'ultima capsula sul flusso è stata troncata, questo deve (MUST) essere trattato come se fosse un messaggio mal formato o incompleto.
3.4. Il campo di intestazione Capsule-Protocol (The Capsule-Protocol Header Field)
Il campo di intestazione "Capsule-Protocol" è un campo strutturato di tipo Item; vedere la sezione 3.3 di [STRUCTURED-FIELDS]. Il suo valore deve (MUST) essere un booleano; qualsiasi altro tipo di valore deve (MUST) essere gestito come se il campo non fosse presente dai destinatari (ad esempio, se questo campo è incluso più volte, il suo tipo diventerà una Lista e il campo verrà ignorato). Questo documento non definisce alcun parametro per il valore del campo di intestazione Capsule-Protocol, ma documenti futuri potrebbero definire parametri. I ricevitori devono (MUST) ignorare i parametri sconosciuti.
Gli endpoint indicano che il protocollo Capsule è in uso su un flusso di dati inviando un campo di intestazione Capsule-Protocol con un valore vero. Un campo di intestazione Capsule-Protocol con un valore falso ha la stessa semantica di quando l'intestazione non è presente.
Gli intermediari possono (MAY) utilizzare questo campo di intestazione per consentire l'elaborazione di datagrammi HTTP per token di upgrade HTTP sconosciuti. Si noti che ciò è possibile solo per HTTP Upgrade o Extended CONNECT.
Il campo di intestazione Capsule-Protocol non deve (MUST NOT) essere utilizzato su risposte HTTP con un codice di stato che sia sia diverso da 101 (Cambio di protocolli) sia al di fuori dell'intervallo 2xx (Riuscito).
Quando si utilizza il protocollo Capsule, gli endpoint HTTP dovrebbero (SHOULD) inviare il campo di intestazione Capsule-Protocol per semplificare l'elaborazione intermedia. Le definizioni di nuovi token di upgrade HTTP che utilizzano il protocollo Capsule possono (MAY) modificare questa raccomandazione.
3.5. La capsula DATAGRAM (The DATAGRAM Capsule)
Questo documento definisce il tipo di capsula DATAGRAM (0x00). Questa capsula consente di inviare datagrammi HTTP su un flusso utilizzando il protocollo Capsule. Ciò è particolarmente utile quando HTTP viene eseguito su un trasporto che non supporta il frame QUIC DATAGRAM.
Datagram Capsule {
Type (i) = 0x00,
Length (i),
HTTP Datagram Payload (..),
}
Figura 4: Formato della capsula DATAGRAM
HTTP Datagram Payload: Il payload del datagramma, la cui semantica è definita dall'estensione che utilizza i datagrammi HTTP. Si noti che questo campo può essere vuoto.
I datagrammi HTTP inviati utilizzando la capsula DATAGRAM hanno la stessa semantica di quelli inviati nei frame QUIC DATAGRAM. In particolare, le restrizioni su quando è consentito inviare un datagramma HTTP e come elaborarli (dalla sezione 2.1) si applicano anche ai datagrammi HTTP inviati e ricevuti utilizzando la capsula DATAGRAM.
Un intermediario può ricodificare i datagrammi HTTP mentre li inoltra. In altre parole, un intermediario può (MAY) inviare una capsula DATAGRAM per inoltrare un datagramma HTTP che è stato ricevuto in un frame QUIC DATAGRAM e viceversa. Gli intermediari non devono (MUST NOT) eseguire questa ricodifica a meno che non abbiano identificato l'uso del protocollo Capsule sul flusso di richiesta corrispondente; vedere la sezione 3.2.
Si noti che mentre le capsule DATAGRAM, che vengono inviate su un flusso, vengono consegnate in modo affidabile in ordine, gli intermediari possono ricodificare le capsule DATAGRAM in frame QUIC DATAGRAM quando inoltrano messaggi, il che potrebbe causare perdita o riordinamento.
Se un intermediario riceve un datagramma HTTP in un frame QUIC DATAGRAM e lo inoltra su una connessione che supporta i frame QUIC DATAGRAM, l'intermediario non dovrebbe (SHOULD NOT) convertire quel datagramma HTTP in una capsula DATAGRAM. Se il datagramma HTTP è troppo grande per stare in un frame DATAGRAM (ad esempio, perché il Path MTU (PMTU) di quella connessione QUIC è troppo basso o se la dimensione massima del payload UDP pubblicizzata su quella connessione è troppo bassa), l'intermediario dovrebbe (SHOULD) scartare il datagramma HTTP invece di convertirlo in una capsula DATAGRAM. Ciò preserva la caratteristica di inaffidabilità end-to-end su cui metodi come Datagram Packetization Layer PMTU Discovery (DPLPMTUD) dipendono [DPLPMTUD]. Un intermediario che converte i frame QUIC DATAGRAM in capsule DATAGRAM consente ai datagrammi HTTP di essere arbitrariamente grandi senza subire perdite. Ciò può rappresentare in modo errato le vere proprietà del percorso, vanificando metodi come DPLPMTUD.
Sebbene le capsule DATAGRAM possano teoricamente trasportare un payload di lunghezza 2^62-1, la maggior parte delle estensioni HTTP che utilizzano datagrammi HTTP avrà i propri limiti su quali dimensioni di payload di datagramma sono pratiche. Le implementazioni dovrebbero (SHOULD) tenere conto di questi limiti durante l'analisi delle capsule DATAGRAM. Se una capsula DATAGRAM in arrivo ha una lunghezza nota per essere così grande da non essere utilizzabile, l'implementazione dovrebbe (SHOULD) scartare la capsula senza bufferizzare il suo contenuto in memoria.
Poiché i frame QUIC DATAGRAM devono rientrare in un pacchetto QUIC, le implementazioni che ricodificano le capsule DATAGRAM in frame QUIC DATAGRAM potrebbero essere tentate di accumulare l'intera capsula nel flusso prima di ricodificarla. Questo dovrebbe (SHOULD) essere evitato, perché può causare problemi di controllo del flusso; vedere la sezione 3.2.
Si noti che è possibile per un'estensione HTTP utilizzare datagrammi HTTP senza utilizzare il protocollo Capsule. Ad esempio, se un'estensione HTTP che utilizza datagrammi HTTP è definita solo su trasporti che supportano i frame QUIC DATAGRAM, potrebbe non aver bisogno di una codifica di flusso. Inoltre, le estensioni HTTP possono utilizzare datagrammi HTTP con il proprio protocollo di flusso di dati. Tuttavia, le nuove estensioni HTTP che desiderano utilizzare datagrammi HTTP dovrebbero (SHOULD) utilizzare il protocollo Capsule, poiché non farlo renderà più difficile per l'estensione HTTP supportare versioni di HTTP diverse da HTTP/3 e impedirà l'interoperabilità con intermediari che supportano solo il protocollo Capsule.