Passa al contenuto principale

Appendice A. Storia delle versioni di HTTP

HTTP è in uso dal 1990. La prima versione, in seguito denominata HTTP/0.9, era un protocollo semplice per il trasferimento di dati ipertestuali attraverso Internet, che usava un solo metodo di richiesta (GET) e nessun metadato. HTTP/1.0, come definito in [RFC1945], ha aggiunto una gamma di metodi di richiesta e una messaggistica simile a MIME, consentendo di trasferire metadati e di porre modificatori sulla semantica di richiesta/risposta. Tuttavia, HTTP/1.0 non ha tenuto sufficientemente conto degli effetti dei proxy gerarchici, della cache, della necessità di connessioni persistenti o degli host virtuali basati sul nome. La proliferazione di applicazioni implementate in modo incompleto che si autodefinivano "HTTP/1.0" ha inoltre reso necessario un cambio di versione del protocollo affinché due applicazioni comunicanti potessero determinare le reciproche reali capacità.

HTTP/1.1 rimane compatibile con HTTP/1.0 includendo requisiti più stringenti che abilitano implementazioni affidabili, aggiungendo solo quelle funzionalità che possono essere ignorate in modo sicuro da un destinatario HTTP/1.0 oppure essere inviate solo quando si comunica con una controparte che dichiara la conformità a HTTP/1.1.

HTTP/1.1 è stato progettato per rendere facile il supporto delle versioni precedenti. Un server HTTP/1.1 di uso generale dovrebbe essere in grado di comprendere qualsiasi richiesta valida nel formato di HTTP/1.0, rispondendo in modo appropriato con un messaggio HTTP/1.1 che usa solo funzionalità comprese (o ignorate in modo sicuro) dai client HTTP/1.0. Allo stesso modo, ci si può aspettare che un client HTTP/1.1 comprenda qualsiasi risposta HTTP/1.0 valida.

Poiché HTTP/0.9 non supportava i campi di intestazione in una richiesta, non esiste un meccanismo che gli permetta di supportare gli host virtuali basati sul nome (selezione della risorsa mediante l'ispezione del campo di intestazione Host). Qualsiasi server che implementi host virtuali basati sul nome dovrebbe disabilitare il supporto per HTTP/0.9. La maggior parte delle richieste che sembrano essere HTTP/0.9 sono, in realtà, richieste HTTP/1.x costruite male, causate da un client che non riesce a codificare correttamente il request-target.

A.1. Modifiche rispetto a HTTP/1.0​

Questa sezione riassume le principali differenze tra le versioni HTTP/1.0 e HTTP/1.1.

A.1.1. Server web multihomed​

I requisiti che client e server supportino il campo di intestazione Host (Sezione 5.4), segnalino un errore se manca da una richiesta HTTP/1.1 e accettino URI assoluti (Sezione 5.3) sono tra le modifiche più importanti definite da HTTP/1.1.

I vecchi client HTTP/1.0 presupponevano una relazione uno-a-uno tra indirizzi IP e server; non esisteva alcun altro meccanismo consolidato per distinguere il server previsto di una richiesta se non l'indirizzo IP a cui quella richiesta era diretta. Il campo di intestazione Host è stato introdotto durante lo sviluppo di HTTP/1.1 e, sebbene sia stato rapidamente implementato dalla maggior parte dei browser HTTP/1.0, sono stati posti requisiti aggiuntivi su tutte le richieste HTTP/1.1 per garantire un'adozione completa. Al momento della stesura di questo documento, la maggior parte dei servizi basati su HTTP dipende dal campo di intestazione Host per indirizzare le richieste.

A.1.2. Connessioni Keep-Alive​

In HTTP/1.0, ogni connessione è stabilita dal client prima della richiesta e chiusa dal server dopo l'invio della risposta. Tuttavia, alcune implementazioni realizzano la versione esplicitamente negoziata ("Keep-Alive") delle connessioni persistenti descritta nella Sezione 19.7.1 di [RFC2068].

Alcuni client e server potrebbero desiderare di essere compatibili con questi precedenti approcci alle connessioni persistenti, negoziandole esplicitamente con un campo di intestazione di richiesta "Connection: keep-alive". Tuttavia, alcune implementazioni sperimentali delle connessioni persistenti HTTP/1.0 sono difettose; ad esempio, se un server proxy HTTP/1.0 non comprende Connection, inoltrerà erroneamente quel campo di intestazione al successivo server in entrata, con il risultato di una connessione bloccata.

Una soluzione tentata fu l'introduzione di un campo di intestazione Proxy-Connection, mirato specificamente ai proxy. In pratica, anche questo era inattuabile, perché i proxy sono spesso distribuiti su più livelli, il che ripropone lo stesso problema discusso sopra.

Di conseguenza, i client sono incoraggiati a non inviare il campo di intestazione Proxy-Connection in nessuna richiesta.

I client sono inoltre incoraggiati a valutare con attenzione l'uso di Connection: keep-alive nelle richieste; sebbene esso possa abilitare connessioni persistenti con server HTTP/1.0, i client che lo usano dovranno monitorare la connessione per individuare richieste "bloccate" (il che indica che il client dovrebbe smettere di inviare il campo di intestazione), e questo meccanismo non dovrebbe essere usato affatto dai client quando si utilizza un proxy.

A.1.3. Introduzione di Transfer-Encoding​

HTTP/1.1 introduce il campo di intestazione Transfer-Encoding (Sezione 3.3.1). Le transfer coding devono essere decodificate prima di inoltrare un messaggio HTTP su un protocollo conforme a MIME.

A.2. Modifiche rispetto alla RFC 2616​

L'approccio di HTTP alla gestione degli errori è stato spiegato. (Sezione 2.5)

La produzione ABNF HTTP-version è stata chiarita come sensibile alle maiuscole. Inoltre, i numeri di versione sono stati limitati a una sola cifra, poiché è noto che le implementazioni gestiscono in modo errato i numeri di versione a più cifre. (Sezione 2.6)

Lo userinfo (cioè nome utente e password) non è più consentito negli URI HTTP e HTTPS, a causa di problemi di sicurezza legati alla loro trasmissione sulla rete. (Sezione 2.7.1)

Lo schema URI HTTPS è ora definito da questa specifica; in precedenza era definito nella Sezione 2.4 di [RFC2818]. Inoltre, esso implica una sicurezza end-to-end. (Sezione 2.7.2)

I messaggi HTTP possono essere (e spesso sono) memorizzati nel buffer dalle implementazioni; nonostante talvolta siano disponibili come flusso, HTTP è fondamentalmente un protocollo orientato ai messaggi. Sono state suggerite dimensioni minime supportate per vari elementi di protocollo, per migliorare l'interoperabilità. (Sezione 3)

Gli spazi bianchi non validi intorno ai field-name ora devono essere rifiutati, perché accettarli rappresenta una vulnerabilità di sicurezza. Le produzioni ABNF che definiscono i campi di intestazione ora elencano solo il valore del campo. (Sezione 3.2)

Le regole sugli spazi bianchi lineari impliciti tra certe produzioni grammaticali sono state rimosse; ora gli spazi bianchi sono consentiti solo dove specificamente definito nell'ABNF. (Sezione 3.2.3)

I campi di intestazione che si estendono su più righe ("line folding") sono deprecati. (Sezione 3.2.4)

L'ottetto NUL non è più consentito nel testo di comment e quoted-string, e la gestione dell'escaping con barra rovesciata al loro interno è stata chiarita. La regola quoted-pair non consente più di effettuare l'escaping di caratteri di controllo diversi da HTAB. Il contenuto non US-ASCII nei campi di intestazione e nella reason phrase è stato reso obsoleto e reso opaco (la regola TEXT è stata rimossa). (Sezione 3.2.6)

I campi di intestazione Content-Length non validi ora devono essere gestiti come errori dai destinatari. (Sezione 3.3.2)

L'algoritmo per determinare la lunghezza del corpo del messaggio è stato chiarito per indicare tutti i casi speciali (ad es. determinati da metodi o codici di stato) che lo influenzano, e che nuovi elementi di protocollo non possono definire tali casi speciali. CONNECT è un nuovo caso speciale nella determinazione della lunghezza del corpo del messaggio. "multipart/byteranges" non è più un modo per determinare la rilevazione della lunghezza del corpo del messaggio. (Sezione 3.3.3)

Il token di transfer coding "identity" è stato rimosso. (Sezioni 3.3 e 4)

La lunghezza del chunk non include il conteggio degli ottetti nell'intestazione e nel trailer del chunk. Il ripiegamento di riga nelle chunk extension non è consentito. (Sezione 4.1)

Il significato della content coding "deflate" è stato chiarito. (Sezione 4.2.2)

I componenti segment + query della RFC 3986 sono stati usati per definire il request-target, invece di abs_path della RFC 1808. La asterisk-form del request-target è consentita solo con il metodo OPTIONS. (Sezione 5.3)

Il termine "Effective Request URI" è stato introdotto. (Sezione 5.5)

I gateway non devono più generare campi di intestazione Via. (Sezione 5.7.1)

È stato chiarito esattamente quando devono essere inviate le opzioni di connessione "close". Inoltre, i campi di intestazione "hop-by-hop" devono comparire nel campo di intestazione Connection; il fatto che siano definiti come hop-by-hop in questa specifica non li esenta. (Sezione 6.1)

Il limite di due connessioni per server è stato rimosso. Non è più richiesto di ritentare una sequenza idempotente di richieste. Il requisito di ritentare le richieste in determinate circostanze quando il server chiude prematuramente la connessione è stato rimosso. Inoltre, alcuni requisiti superflui su quando ai server è consentito chiudere prematuramente le connessioni sono stati rimossi. (Sezione 6.3)

La semantica del campo di intestazione Upgrade è ora definita anche in risposte diverse dalla 101 (ciò è stato recepito da [RFC2817]). Inoltre, l'ordinamento nel valore del campo è ora significativo. (Sezione 6.7)

Gli elementi di lista vuoti nelle produzioni di liste (ad es. un campo di intestazione di lista contenente ", ,") sono stati deprecati. (Sezione 7)

La registrazione delle Transfer Codings ora richiede IETF Review (Sezione 8.4)

Questa specifica definisce ora l'Upgrade Token Registry, definito in precedenza nella Sezione 7.2 di [RFC2817]. (Sezione 8.6)

L'aspettativa di supportare le richieste HTTP/0.9 è stata rimossa. (Appendice A)

Sono evidenziati i problemi con i campi di intestazione Keep-Alive e Proxy-Connection nelle richieste, con l'uso del secondo che è del tutto sconsigliato. (Appendice A.1.2)