2. Architettura
HTTP è stato creato per l'architettura del World Wide Web (WWW) e si è evoluto nel tempo per supportare le esigenze di scalabilità di un sistema ipertestuale mondiale. Gran parte di tale architettura si riflette nella terminologia e nelle produzioni sintattiche usate per definire HTTP.
2.1. Messaggistica client/server
HTTP è un protocollo richiesta/risposta senza stato che opera scambiando messaggi (Sezione 3) attraverso una "connessione" affidabile a livello di trasporto o di sessione (Sezione 6). Un "client" HTTP è un programma che stabilisce una connessione a un server allo scopo di inviare una o più richieste HTTP. Un "server" HTTP è un programma che accetta connessioni per soddisfare le richieste HTTP inviando risposte HTTP.
I termini "client" e "server" si riferiscono soltanto ai ruoli che questi programmi svolgono per una particolare connessione. Lo stesso programma può comportarsi come client su alcune connessioni e come server su altre. Il termine "user agent" si riferisce a uno qualsiasi dei vari programmi client che avviano una richiesta, inclusi (ma non limitati a) browser, spider (robot basati sul web), strumenti a riga di comando, applicazioni personalizzate e app mobili. Il termine "origin server" si riferisce al programma che può generare risposte autorevoli per una determinata risorsa di destinazione. I termini "mittente" e "destinatario" si riferiscono a qualsiasi implementazione che invia o riceve, rispettivamente, un dato messaggio.
HTTP si basa sullo standard Uniform Resource Identifier (URI) [RFC3986] per indicare la risorsa di destinazione (Sezione 5.1) e le relazioni tra le risorse. I messaggi vengono trasmessi in un formato simile a quello usato dalla posta Internet [RFC5322] e dalle Multipurpose Internet Mail Extensions (MIME) [RFC2045] (vedere l'Appendice A di [RFC7231] per le differenze tra i messaggi HTTP e MIME).
La maggior parte della comunicazione HTTP consiste in una richiesta di recupero (GET) di una rappresentazione di qualche risorsa identificata da un URI. Nel caso più semplice, ciò può avvenire tramite un'unica connessione bidirezionale (===) tra lo user agent (UA) e l'origin server (O).
request >
UA ======================================= O
< response
Un client invia una richiesta HTTP a un server sotto forma di messaggio di richiesta, che inizia con una request-line che include un metodo, un URI e la versione del protocollo (Sezione 3.1.1), seguita da campi di intestazione contenenti modificatori di richiesta, informazioni sul client e metadati della rappresentazione (Sezione 3.2), una riga vuota per indicare la fine della sezione di intestazione e infine un corpo del messaggio contenente il payload del corpo (se presente, Sezione 3.3).
Un server risponde alla richiesta di un client inviando uno o più messaggi di risposta HTTP, ciascuno dei quali inizia con una status line che include la versione del protocollo, un codice di successo o di errore e una frase di motivazione testuale (Sezione 3.1.2), eventualmente seguita da campi di intestazione contenenti informazioni sul server, metadati della risorsa e metadati della rappresentazione (Sezione 3.2), una riga vuota per indicare la fine della sezione di intestazione e infine un corpo del messaggio contenente il payload del corpo (se presente, Sezione 3.3).
Una connessione può essere usata per più scambi richiesta/risposta, come definito nella Sezione 6.3.
L'esempio seguente illustra un tipico scambio di messaggi per una richiesta GET (Sezione 4.3.1 di [RFC7231]) sull'URI "http://www.example.com/hello.txt":
Richiesta del client:
GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
Risposta del server:
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My payload includes a trailing CRLF.
2.2. Diversità delle implementazioni
Quando si considera la progettazione di HTTP, è facile cadere nella trappola di pensare che tutti gli user agent siano browser generici e tutti gli origin server siano grandi siti web pubblici. In pratica non è così. Tra i comuni user agent HTTP figurano elettrodomestici, impianti stereo, bilance, script di aggiornamento del firmware, programmi a riga di comando, app mobili e dispositivi di comunicazione di innumerevoli forme e dimensioni. Allo stesso modo, tra i comuni origin server HTTP figurano unità di domotica, componenti di rete configurabili, macchine per ufficio, robot autonomi, feed di notizie, telecamere del traffico, selettori pubblicitari e piattaforme di distribuzione video.
Il termine "user agent" non implica che vi sia un utente umano che interagisce direttamente con l'agente software al momento di una richiesta. In molti casi, uno user agent è installato o configurato per essere eseguito in background e conservare i risultati per una successiva ispezione (oppure per conservare solo un sottoinsieme di quei risultati che potrebbero essere interessanti o errati). Gli spider, ad esempio, ricevono tipicamente un URI di partenza e sono configurati per seguire un certo comportamento mentre esplorano il Web come grafo ipertestuale.
La diversità delle implementazioni di HTTP implica che non tutti gli user agent possano fornire suggerimenti interattivi al proprio utente o avvisi adeguati in merito a problemi di sicurezza o privacy. Nei pochi casi in cui questa specifica richiede di segnalare errori all'utente, è accettabile che tale segnalazione sia osservabile soltanto in una console di errore o in un file di log. Allo stesso modo, i requisiti secondo cui un'azione automatizzata deve essere confermata dall'utente prima di procedere possono essere soddisfatti tramite scelte di configurazione preventiva, opzioni di esecuzione o la semplice evitazione dell'azione non sicura; la conferma non implica alcuna specifica interfaccia utente né l'interruzione dell'elaborazione normale, se l'utente ha già effettuato quella scelta.
2.3. Intermediari
HTTP consente l'uso di intermediari per soddisfare le richieste attraverso una catena di connessioni. Esistono tre forme comuni di intermediario HTTP: proxy, gateway e tunnel. In alcuni casi, un singolo intermediario può agire come origin server, proxy, gateway o tunnel, cambiando comportamento in base alla natura di ciascuna richiesta.
> > > >
UA =========== A =========== B =========== C =========== O
< < < <
Il diagramma qui sopra mostra tre intermediari (A, B e C) tra lo user agent e l'origin server. Un messaggio di richiesta o di risposta che percorre l'intera catena attraverserà quattro connessioni separate. Alcune opzioni di comunicazione HTTP possono applicarsi solo alla connessione con il vicino più prossimo non tunnel, solo agli estremi della catena, oppure a tutte le connessioni lungo la catena. Sebbene il diagramma sia lineare, ciascun partecipante può essere impegnato in più comunicazioni simultanee. Ad esempio, B può ricevere richieste da molti client diversi da A e/o inoltrare richieste a server diversi da C nello stesso momento in cui gestisce la richiesta di A. Allo stesso modo, richieste successive possono essere inviate lungo un percorso di connessioni diverso, spesso in base a una configurazione dinamica per il bilanciamento del carico.
I termini "upstream" e "downstream" sono usati per descrivere requisiti direzionali in relazione al flusso dei messaggi: tutti i messaggi fluiscono da upstream a downstream. I termini "inbound" e "outbound" sono usati per descrivere requisiti direzionali in relazione al percorso della richiesta: "inbound" significa verso l'origin server e "outbound" significa verso lo user agent.
Un "proxy" è un agente di inoltro di messaggi selezionato dal client, di solito tramite regole di configurazione locali, per ricevere richieste per uno o più tipi di URI assoluti e tentare di soddisfarle tramite traduzione attraverso l'interfaccia HTTP. Alcune traduzioni sono minime, come per le richieste proxy per URI "http", mentre altre richieste possono richiedere la traduzione da e verso protocolli a livello di applicazione del tutto diversi. I proxy sono spesso usati per raggruppare le richieste HTTP di un'organizzazione attraverso un intermediario comune ai fini della sicurezza, di servizi di annotazione o di cache condivisa. Alcuni proxy sono progettati per applicare trasformazioni a messaggi o payload selezionati mentre vengono inoltrati, come descritto nella Sezione 5.7.2.
Un "gateway" (detto anche "reverse proxy") è un intermediario che agisce come origin server per la connessione outbound ma traduce le richieste ricevute e le inoltra in entrata a un altro o ad altri server. I gateway sono spesso usati per incapsulare servizi informativi legacy o non attendibili, per migliorare le prestazioni del server tramite caching "acceleratore" e per consentire il partizionamento o il bilanciamento del carico dei servizi HTTP su più macchine.
Tutti i requisiti HTTP applicabili a un origin server si applicano anche alla comunicazione outbound di un gateway. Un gateway comunica con i server in entrata usando qualsiasi protocollo desideri, incluse estensioni private a HTTP che sono al di fuori dell'ambito di questa specifica. Tuttavia, un gateway da HTTP a HTTP che desideri interoperare con server HTTP di terze parti dovrebbe conformarsi ai requisiti degli user agent sulla connessione in entrata del gateway.
Un "tunnel" agisce come relè cieco tra due connessioni senza modificare i messaggi. Una volta attivo, un tunnel non è considerato una parte della comunicazione HTTP, sebbene il tunnel possa essere stato avviato da una richiesta HTTP. Un tunnel cessa di esistere quando entrambe le estremità della connessione inoltrata vengono chiuse. I tunnel sono usati per estendere una connessione virtuale attraverso un intermediario, ad esempio quando Transport Layer Security (TLS, [RFC5246]) è usato per stabilire una comunicazione riservata attraverso un proxy firewall condiviso.
Le categorie di intermediari sopra descritte considerano solo quelli che agiscono come partecipanti alla comunicazione HTTP. Esistono anche intermediari che possono agire su livelli inferiori dello stack di protocolli di rete, filtrando o reindirizzando il traffico HTTP senza la conoscenza o il permesso dei mittenti dei messaggi. Gli intermediari di rete sono indistinguibili (a livello di protocollo) da un attacco man-in-the-middle e spesso introducono difetti di sicurezza o problemi di interoperabilità violando erroneamente la semantica di HTTP.
Ad esempio, un "interception proxy" [RFC3040] (comunemente noto anche come "transparent proxy" [RFC1919] o "captive portal") differisce da un proxy HTTP perché non è selezionato dal client. Un interception proxy, invece, filtra o reindirizza i pacchetti TCP in uscita sulla porta 80 (e occasionalmente altro traffico su porte comuni). Gli interception proxy si trovano comunemente nei punti di accesso di rete pubblici, come mezzo per imporre l'abbonamento all'account prima di consentire l'uso di servizi Internet non locali, e all'interno dei firewall aziendali per far rispettare le politiche di utilizzo della rete.
HTTP è definito come un protocollo senza stato, il che significa che ogni messaggio di richiesta può essere compreso isolatamente. Molte implementazioni si affidano alla progettazione senza stato di HTTP per riutilizzare connessioni proxy o per bilanciare dinamicamente le richieste su più server. Pertanto, un server MUST NOT presumere che due richieste sulla stessa connessione provengano dallo stesso user agent, a meno che la connessione non sia protetta e specifica di quell'agente. Alcune estensioni HTTP non standard (ad es. [RFC4559]) sono note per violare questo requisito, causando problemi di sicurezza e di interoperabilità.
2.4. Cache
Una "cache" è un archivio locale di messaggi di risposta precedenti e il sottosistema che ne controlla la memorizzazione, il recupero e la cancellazione. Una cache memorizza le risposte memorizzabili in cache per ridurre il tempo di risposta e il consumo di larghezza di banda della rete nelle future richieste equivalenti. Qualsiasi client o server MAY usare una cache, sebbene una cache non possa essere usata da un server mentre questo agisce come tunnel.
L'effetto di una cache è che la catena richiesta/risposta viene accorciata se uno dei partecipanti lungo la catena dispone di una risposta in cache applicabile a quella richiesta. Quanto segue illustra la catena risultante se B ha una copia in cache di una risposta precedente di O (tramite C) per una richiesta che non è stata messa in cache da UA o A.
> >
UA =========== A =========== B - - - - - - C - - - - - - O
< <
Una risposta è "memorizzabile in cache" se a una cache è consentito memorizzare una copia del messaggio di risposta da usare per rispondere a richieste successive. Anche quando una risposta è memorizzabile in cache, il client o l'origin server possono imporre ulteriori vincoli su quando tale risposta in cache può essere usata per una particolare richiesta. I requisiti HTTP per il comportamento della cache e per le risposte memorizzabili in cache sono definiti nella Sezione 2 di [RFC7234].
Esiste una grande varietà di architetture e configurazioni di cache distribuite in tutto il World Wide Web e all'interno di grandi organizzazioni. Tra queste figurano gerarchie nazionali di proxy cache per risparmiare larghezza di banda transoceanica, sistemi collaborativi che diffondono in broadcast o multicast le voci di cache, archivi di voci di cache pre-recuperate da usare in ambienti offline o ad alta latenza, e così via.
2.5. Conformità e gestione degli errori
Questa specifica si propone criteri di conformità in base al ruolo di un partecipante nella comunicazione HTTP. Pertanto, i requisiti HTTP sono posti su mittenti, destinatari, client, server, user agent, intermediari, origin server, proxy, gateway o cache, a seconda di quale comportamento viene vincolato dal requisito. Ulteriori requisiti (sociali) sono posti su implementazioni, proprietari di risorse e registrazioni di elementi di protocollo quando si applicano oltre l'ambito di una singola comunicazione.
Il verbo "generate" è usato al posto di "send" quando un requisito distingue tra la creazione di un elemento di protocollo e il mero inoltro a valle di un elemento ricevuto.
Un'implementazione è considerata conforme se rispetta tutti i requisiti associati ai ruoli che ricopre in HTTP.
La conformità comprende sia la sintassi sia la semantica degli elementi di protocollo. Un mittente MUST NOT generare elementi di protocollo che veicolano un significato che quel mittente sa essere falso. Un mittente MUST NOT generare elementi di protocollo che non corrispondono alla grammatica definita dalle corrispondenti regole ABNF. All'interno di un dato messaggio, un mittente MUST NOT generare elementi di protocollo o alternative sintattiche che è consentito generare solo ai partecipanti in altri ruoli (ovvero un ruolo che il mittente non ricopre per quel messaggio).
Quando un elemento di protocollo ricevuto viene analizzato, il destinatario MUST essere in grado di analizzare qualsiasi valore di lunghezza ragionevole che sia applicabile al ruolo del destinatario e che corrisponda alla grammatica definita dalle corrispondenti regole ABNF. Si noti, tuttavia, che alcuni elementi di protocollo ricevuti potrebbero non essere analizzati. Ad esempio, un intermediario che inoltra un messaggio può analizzare un campo di intestazione in componenti generici field-name e field-value, ma inoltrare poi il campo di intestazione senza ulteriori analisi all'interno del field-value.
HTTP non ha limiti di lunghezza specifici per molti dei suoi elementi di protocollo, perché le lunghezze che potrebbero essere appropriate variano ampiamente in base al contesto di distribuzione e allo scopo dell'implementazione. Pertanto, l'interoperabilità tra mittenti e destinatari dipende da aspettative condivise riguardo a ciò che costituisce una lunghezza ragionevole per ciascun elemento di protocollo. Inoltre, ciò che è comunemente inteso come lunghezza ragionevole per alcuni elementi di protocollo è cambiato nel corso dei due decenni passati di uso di HTTP e si prevede che continuerà a cambiare in futuro.
Come minimo, un destinatario MUST essere in grado di analizzare ed elaborare lunghezze di elementi di protocollo almeno pari ai valori che esso genera per quegli stessi elementi di protocollo in altri messaggi. Ad esempio, un origin server che pubblica riferimenti URI molto lunghi per le proprie risorse deve essere in grado di analizzare ed elaborare quegli stessi riferimenti quando li riceve come request target.
Un destinatario MUST interpretare un elemento di protocollo ricevuto secondo la semantica definita per esso da questa specifica, incluse le estensioni a questa specifica, a meno che il destinatario non abbia stabilito (per esperienza o configurazione) che il mittente implementa in modo errato ciò che è implicato da quella semantica. Ad esempio, un origin server potrebbe ignorare il contenuto di un campo di intestazione Accept-Encoding ricevuto se l'ispezione del campo di intestazione User-Agent indica una specifica versione di implementazione nota per fallire alla ricezione di certe codifiche di contenuto.
Salvo diversa indicazione, un destinatario MAY tentare di recuperare un elemento di protocollo utilizzabile da un costrutto non valido. HTTP non definisce meccanismi specifici di gestione degli errori, tranne quando hanno un impatto diretto sulla sicurezza, poiché applicazioni diverse del protocollo richiedono strategie di gestione degli errori diverse. Ad esempio, un browser web potrebbe voler recuperare in modo trasparente da una risposta in cui il campo di intestazione Location non viene analizzato secondo l'ABNF, mentre un client di controllo di sistemi potrebbe considerare pericolosa qualsiasi forma di recupero dagli errori.
2.6. Versionamento del protocollo
HTTP usa uno schema di numerazione "
La versione di un messaggio HTTP è indicata da un campo HTTP-version nella prima riga del messaggio. HTTP-version è sensibile alle maiuscole.
HTTP-version = HTTP-name "/" DIGIT "." DIGIT
HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive
Il numero di versione di HTTP è composto da due cifre decimali separate da un "." (punto o punto decimale). La prima cifra ("major version") indica la sintassi dei messaggi HTTP, mentre la seconda cifra ("minor version") indica la più alta versione minore all'interno di quella versione maggiore alla quale il mittente è conforme ed è in grado di comprendere per comunicazioni future. La versione minore pubblicizza le capacità di comunicazione del mittente anche quando il mittente usa solo un sottoinsieme retrocompatibile del protocollo, consentendo così al destinatario di sapere che funzionalità più avanzate possono essere usate in risposta (dai server) o in richieste future (dai client).
Quando un messaggio HTTP/1.1 viene inviato a un destinatario HTTP/1.0 [RFC1945] o a un destinatario la cui versione è sconosciuta, il messaggio HTTP/1.1 è costruito in modo che possa essere interpretato come un messaggio HTTP/1.0 valido se tutte le funzionalità più recenti vengono ignorate. Questa specifica impone requisiti relativi alla versione del destinatario su alcune funzionalità nuove, cosicché un mittente conforme userà solo funzionalità compatibili finché non abbia stabilito, tramite configurazione o ricezione di un messaggio, che il destinatario supporta HTTP/1.1.
L'interpretazione di un campo di intestazione non cambia tra versioni minori della stessa versione maggiore di HTTP, sebbene il comportamento predefinito di un destinatario in assenza di tale campo possa cambiare. Salvo diversa indicazione, i campi di intestazione definiti in HTTP/1.1 sono definiti per tutte le versioni di HTTP/1.x. In particolare, i campi di intestazione Host e Connection dovrebbero essere implementati da tutte le implementazioni HTTP/1.x, indipendentemente dal fatto che dichiarino la conformità a HTTP/1.1.
Nuovi campi di intestazione possono essere introdotti senza cambiare la versione del protocollo se la loro semantica definita consente di ignorarli in modo sicuro da parte di destinatari che non li riconoscono. L'estensibilità dei campi di intestazione è discussa nella Sezione 3.2.1.
Gli intermediari che elaborano messaggi HTTP (cioè tutti gli intermediari diversi da quelli che agiscono come tunnel) MUST inviare la propria HTTP-version nei messaggi inoltrati. In altre parole, non è loro consentito inoltrare ciecamente la prima riga di un messaggio HTTP senza assicurarsi che la versione del protocollo in quel messaggio corrisponda a una versione alla quale quell'intermediario è conforme sia per la ricezione sia per l'invio dei messaggi. L'inoltro di un messaggio HTTP senza riscrivere la HTTP-version potrebbe causare errori di comunicazione quando i destinatari a valle usano la versione del mittente del messaggio per determinare quali funzionalità sia sicuro usare per successive comunicazioni con quel mittente.
Un client SHOULD inviare una versione di richiesta pari alla versione più alta alla quale il client è conforme e la cui versione maggiore non sia superiore alla versione più alta supportata dal server, se questa è nota. Un client MUST NOT inviare una versione alla quale non è conforme.
Un client MAY inviare una versione di richiesta inferiore se è noto che il server implementa in modo errato la specifica HTTP, ma solo dopo che il client ha tentato almeno una richiesta normale e ha stabilito dal codice di stato della risposta o dai campi di intestazione (ad es. Server) che il server gestisce in modo improprio versioni di richiesta più alte.
Un server SHOULD inviare una versione di risposta pari alla versione più alta alla quale il server è conforme e che abbia una versione maggiore minore o uguale a quella ricevuta nella richiesta. Un server MUST NOT inviare una versione alla quale non è conforme. Un server può inviare una risposta 505 (HTTP Version Not Supported) se desidera, per qualsiasi motivo, rifiutare il servizio della versione maggiore del protocollo del client.
Un server MAY inviare una risposta HTTP/1.0 a una richiesta se è noto o si sospetta che il client implementi in modo errato la specifica HTTP e non sia in grado di elaborare correttamente risposte di versioni successive, ad esempio quando un client non riesce ad analizzare correttamente il numero di versione o quando un intermediario è noto per inoltrare ciecamente la HTTP-version anche quando non è conforme alla data versione minore del protocollo. Tali downgrade del protocollo SHOULD NOT essere eseguiti, a meno che non siano attivati da specifici attributi del client, come quando uno o più campi di intestazione della richiesta (ad es. User-Agent) corrispondono univocamente ai valori inviati da un client noto per essere in errore.
L'intenzione della progettazione del versionamento di HTTP è che il numero maggiore venga incrementato solo se viene introdotta una sintassi di messaggio incompatibile, e che il numero minore venga incrementato solo quando le modifiche apportate al protocollo hanno l'effetto di aggiungere qualcosa alla semantica dei messaggi o di implicare capacità aggiuntive del mittente. Tuttavia, la versione minore non è stata incrementata per le modifiche introdotte tra la [RFC2068] e la [RFC2616], e questa revisione ha evitato specificamente qualsiasi modifica di questo tipo al protocollo.
Quando un messaggio HTTP viene ricevuto con un numero di versione maggiore che il destinatario implementa, ma con un numero di versione minore superiore a quello che il destinatario implementa, il destinatario SHOULD elaborare il messaggio come se fosse nella versione minore più alta all'interno di quella versione maggiore alla quale il destinatario è conforme. Un destinatario può presumere che un messaggio con una versione minore più alta, quando inviato a un destinatario che non ha ancora indicato il supporto per quella versione più alta, sia sufficientemente retrocompatibile da essere elaborato in modo sicuro da qualsiasi implementazione della stessa versione maggiore.
2.7. Uniform Resource Identifier
Gli Uniform Resource Identifier (URI) [RFC3986] sono usati in tutto HTTP come mezzo per identificare le risorse (Sezione 2 di [RFC7231]). I riferimenti URI sono usati per indirizzare le richieste, indicare i reindirizzamenti e definire le relazioni.
Le definizioni di "URI-reference", "absolute-URI", "relative-part", "scheme", "authority", "port", "host", "path-abempty", "segment", "query" e "fragment" sono derivate dalla sintassi generica degli URI. Una regola "absolute-path" è definita per gli elementi di protocollo che possono contenere un componente path non vuoto. (Questa regola differisce leggermente dalla regola path-abempty della RFC 3986, che consente di usare un path vuoto nei riferimenti, e dalla regola path-absolute, che non consente path che iniziano con "//".) Una regola "partial-URI" è definita per gli elementi di protocollo che possono contenere un URI relativo ma non un componente fragment.
URI-reference = <URI-reference, see [RFC3986], Section 4.1>
absolute-URI = <absolute-URI, see [RFC3986], Section 4.3>
relative-part = <relative-part, see [RFC3986], Section 4.2>
scheme = <scheme, see [RFC3986], Section 3.1>
authority = <authority, see [RFC3986], Section 3.2>
uri-host = <host, see [RFC3986], Section 3.2.2>
port = <port, see [RFC3986], Section 3.2.3>
path-abempty = <path-abempty, see [RFC3986], Section 3.3>
segment = <segment, see [RFC3986], Section 3.3>
query = <query, see [RFC3986], Section 3.4>
fragment = <fragment, see [RFC3986], Section 3.5>
absolute-path = 1*( "/" segment )
partial-URI = relative-part [ "?" query ]
Ogni elemento di protocollo in HTTP che consente un riferimento URI indicherà nella sua produzione ABNF se l'elemento consente qualsiasi forma di riferimento (URI-reference), solo un URI in forma assoluta (absolute-URI), solo i componenti path e query opzionale, o una qualche combinazione di quanto sopra. Salvo diversa indicazione, i riferimenti URI sono analizzati relativamente all'effective request URI (Sezione 5.5).
2.7.1. Schema URI http
Lo schema URI "http" è qui definito allo scopo di coniare identificatori in base alla loro associazione con lo spazio dei nomi gerarchico governato da un potenziale origin server HTTP in ascolto di connessioni TCP ([RFC0793]) su una data porta.
http-URI = "http:" "//" authority path-abempty [ "?" query ]
[ "#" fragment ]
L'origin server per un URI "http" è identificato dal componente authority, che include un identificatore di host e una porta TCP opzionale ([RFC3986], Sezione 3.2.2). Il componente path gerarchico e il componente query opzionale fungono da identificatore per una potenziale risorsa di destinazione all'interno dello spazio dei nomi di quell'origin server. Il componente fragment opzionale consente l'identificazione indiretta di una risorsa secondaria, indipendentemente dallo schema URI, come definito nella Sezione 3.5 di [RFC3986].
Un mittente MUST NOT generare un URI "http" con un identificatore di host vuoto. Un destinatario che elabora un tale riferimento URI MUST rifiutarlo come non valido.
Se l'identificatore di host è fornito come indirizzo IP, l'origin server è il listener (se presente) sulla porta TCP indicata a quell'indirizzo IP. Se host è un nome registrato, il nome registrato è un identificatore indiretto da usare con un servizio di risoluzione dei nomi, come il DNS, per trovare un indirizzo per quell'origin server. Se il sottocomponente port è vuoto o non fornito, la porta TCP 80 (la porta riservata ai servizi WWW) è quella predefinita.
Si noti che la presenza di un URI con un dato componente authority non implica che vi sia sempre un server HTTP in ascolto di connessioni su quell'host e quella porta. Chiunque può coniare un URI. Ciò che il componente authority determina è chi ha il diritto di rispondere in modo autorevole alle richieste che prendono di mira la risorsa identificata. La natura delegata dei nomi registrati e degli indirizzi IP crea uno spazio dei nomi federato, basato sul controllo dell'host e della porta indicati, indipendentemente dalla presenza di un server HTTP. Vedere la Sezione 9.1 per le considerazioni di sicurezza relative allo stabilire l'autorità.
Quando un URI "http" viene usato in un contesto che richiede l'accesso alla risorsa indicata, un client MAY tentare l'accesso risolvendo l'host in un indirizzo IP, stabilendo una connessione TCP a quell'indirizzo sulla porta indicata e inviando al server un messaggio di richiesta HTTP (Sezione 3) contenente i dati identificativi dell'URI (Sezione 5). Se il server risponde a quella richiesta con un messaggio di risposta HTTP non provvisorio, come descritto nella Sezione 6 di [RFC7231], allora quella risposta è considerata una risposta autorevole alla richiesta del client.
Sebbene HTTP sia indipendente dal protocollo di trasporto, lo schema "http" è specifico dei servizi basati su TCP, perché il processo di delega dei nomi dipende da TCP per stabilire l'autorità. Un servizio HTTP basato su un altro protocollo di connessione sottostante sarebbe presumibilmente identificato mediante uno schema URI diverso, proprio come lo schema "https" (sotto) è usato per le risorse che richiedono una connessione protetta end-to-end. Altri protocolli potrebbero anche essere usati per fornire accesso a risorse identificate da "http" -- è solo l'interfaccia autorevole a essere specifica di TCP.
La sintassi generica degli URI per authority include anche un sottocomponente userinfo deprecato ([RFC3986], Sezione 3.2.1) per includere informazioni di autenticazione dell'utente nell'URI. Alcune implementazioni fanno uso del componente userinfo per la configurazione interna delle informazioni di autenticazione, ad esempio all'interno di opzioni di invocazione di comandi, file di configurazione o elenchi di segnalibri, anche se tale uso potrebbe esporre un identificatore utente o una password. Un mittente MUST NOT generare il sottocomponente userinfo (e il suo delimitatore "@") quando un riferimento URI "http" viene generato all'interno di un messaggio come request target o valore di campo di intestazione. Prima di fare uso di un riferimento URI "http" ricevuto da una fonte non attendibile, un destinatario SHOULD verificare la presenza di userinfo e trattarne la presenza come un errore; è probabile che venga usato per oscurare l'autorità ai fini di attacchi di phishing.
2.7.2. Schema URI https
Lo schema URI "https" è qui definito allo scopo di coniare identificatori in base alla loro associazione con lo spazio dei nomi gerarchico governato da un potenziale origin server HTTP in ascolto su una data porta TCP per connessioni protette con TLS ([RFC5246]).
Tutti i requisiti elencati sopra per lo schema "http" sono requisiti anche per lo schema "https", tranne per il fatto che la porta TCP 443 è quella predefinita se il sottocomponente port è vuoto o non fornito, e lo user agent MUST assicurarsi che la propria connessione all'origin server sia protetta mediante l'uso di una crittografia robusta, end-to-end, prima di inviare la prima richiesta HTTP.
https-URI = "https:" "//" authority path-abempty [ "?" query ]
[ "#" fragment ]
Si noti che lo schema URI "https" dipende sia da TLS sia da TCP per stabilire l'autorità. Le risorse rese disponibili tramite lo schema "https" non hanno un'identità condivisa con lo schema "http" anche se i loro identificatori di risorsa indicano la stessa authority (lo stesso host in ascolto sulla stessa porta TCP). Sono spazi dei nomi distinti e sono considerati origin server distinti. Tuttavia, un'estensione a HTTP definita per applicarsi a interi domini host, come il protocollo Cookie [RFC6265], può consentire che le informazioni impostate da un servizio influenzino la comunicazione con altri servizi all'interno di un gruppo corrispondente di domini host.
Il processo per l'accesso autorevole a una risorsa identificata da "https" è definito in [RFC2818].
2.7.3. Normalizzazione e confronto degli URI http e https
Poiché gli schemi "http" e "https" sono conformi alla sintassi generica degli URI, tali URI sono normalizzati e confrontati secondo l'algoritmo definito nella Sezione 6 di [RFC3986], usando i valori predefiniti sopra descritti per ciascuno schema.
Se la porta è uguale alla porta predefinita per uno schema, la forma normale è omettere il sottocomponente port. Quando non viene usato in forma assoluta come request target di una richiesta OPTIONS, un componente path vuoto è equivalente a un path assoluto "/", quindi la forma normale è fornire invece un path "/". Lo schema e l'host non distinguono maiuscole e minuscole e sono normalmente forniti in minuscolo; tutti gli altri componenti sono confrontati in modo sensibile alle maiuscole. I caratteri diversi da quelli nell'insieme "reserved" sono equivalenti ai loro ottetti codificati in percentuale: la forma normale è non codificarli (vedere le Sezioni 2.1 e 2.2 di [RFC3986]).
Ad esempio, i tre URI seguenti sono equivalenti:
http://example.com:80/~smith/home.html
http://EXAMPLE.com/%7Esmith/home.html
http://EXAMPLE.com:/%7esmith/home.html