Questo protocollo è implementato su due host (client e server) che si scambiano messaggi mediante HTTP. Il protocollo definisce sia la struttura dei messaggi, sia il modo in cui vengono scambiati.
Prima di descrivere il protocollo facciamo luce sulla nomenclatura che lo interessa. Una pagina web è in genere un documento html. Definiamo il documento html come un oggetto.
Il documento html può indirizzare più oggetti. Ad esempio una pagina web con 3 immagini è composta da questi 3 oggetti più un quarto oggetto che è il documento html. Html si riferisce ad un oggetto mediante l’URL:
http://www.nomeserver.com/directory1/directory2/…/img.png
La pagina html è ospitata (hostata) in un web server.
Un browser invia richieste HTTP per indirizzare oggetti web al server, che invia delle risposte. Un server è sempre attivo (pronto a ricevere delle richieste) e ha un indirizzo IP statico e noto. Inoltre un server, potenzialmente, può ricevere richieste da milioni di client nella rete.
Il protocollo HTTP si serve del protocollo TCP per il trasporto.
TCP garantirà la consegna dei messaggi di HTTP.
Vantaggio della suddivisione a livello: HTTP non deve preoccuparsi di come TCP applichi il trasporto, della perdita e del recupero dei messaggi, e questo ad HTTP non interessa, il suo compito è solo quello di inviare il messaggio sulla sua socket, mentre TCP prende in carico il trasporto verso la socket di destinazione. HTTP è un protocollo senza memoria di stato, cioè i server non tengono conto dello stato dei client. Per esempio se un client richiede la stessa pagina nel giro di pochi secondi, il server la invierà di nuovo.
I protocollo di trasporto (TCP nel caso di HTTP) richiede che lo sviluppatore prenda una decisione riguardo una cosa: una volta che i messaggi di richiesta sono stati ricevuti dal server, questo deve inviare i messaggi sulla stessa connessione TCP instaurata nel viaggio di andata del messaggio, o deve instaurare una nuova connessione TCP? Nel primo caso si parla di connessioni persistenti, nel secondo non persistenti. Analizziamo i due casi.
Seguiamo i passi che servono ad un client per richiedere e ricevere una pagina html e 10 immagini (11 oggetti) che risiedono nello stesso server del documento html al sito:
http://universita.com/informatica/home.index
La connessione TCP viene chiusa dopo che il client ha ricevuto il messaggio di risposta dal server. Quindi la connessione non è persistente.
Inoltre per quanto riguarda le richieste, si considera come se in questo caso fossero fatte una per volta, in realtà i browser consentono di impostare il numero di connessione parallele. Normalmente i browser eseguono 5-10 connessioni TCP parallele.
Cerchiamo di capire quanto tempo occorre per una connessione non persistente.
Definiamo l'RTT come il tempo che impiega un pacchetto per viaggiare dal client al server e poi tornare indietro.
Vediamo ora cosa succede quando un utente fa click con mouse su un URL.
Il browser inizializza una connessione TCP, questo comporta un handshake a tre vie, ovvero un client invia un piccolo pacchetto TCP al server, il server risponde per far capire al client che ha ricevuto il pacchetto (1 RTT) e il client ne invia un altro per confermare di aver ricevuto la conferma del server insieme alla richiesta HTTP. Quando il server risponde alla richiesta HTTP con la pagina richiesta saranno stati raggiunti 2 RTT. Una connessione senza persistenza richiede 2 RTT.
Le connessioni non persistenti hanno alcuni limiti: il primo è che per ogni oggetto richiesto occorre stabilire e mantenere un nuova connessione TCP, il che richiede l'allocazione delle risorse necessarie sia al client che al server (buffer, …). Questo non è positivo soprattutto per il server che potenzialmente può ricevere richieste da centinaia di client.
Nelle connessioni persistenti il server non chiude la connessione con il client dopo l'invio di un certo oggetto, ma la mantiene. Il che vuol dire che più oggetti possono essere inviati sulla stessa connessione. Quindi un intera pagina web può essere inviata attraverso una connessione precedentemente stabilita, ma non solo, anche più di un sito web possono essere inviati, se il client ne fa successivamente richiesta.
HTTP definisce due tipi di messaggi: messaggi di richiesta e messaggi di risposta.
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-agent: Mozzilla/5.0
Accept-language: fr
Un messaggio HTTP può essere di lunghezza indefinita, anche solo di una riga.
La prima riga indica che è stata fata una richiesta di tipo GET (può assumere anche tipo POST, HEAD, PUT, DELETE).
La seconda riga indica il server a cui è fatta la richiesta.
La terza riga indica il tipo di browser che sta facendo la richiesta.
La quarta riga è solo una delle tante informazioni che si può condividere con un messaggio di richiesta HTTP.
Vediamo il formato generale di una richiesta:
Lo schema generale di richiesta è molto simile alla richiesta che abbiamo visto precedentemente. Nell'esempio sopra il campo body è vuoto, poiché si tratta di una richiesta di tipo GET. Il campo body si riempie quando la richiesta è di tipo POST (per esempio quando l'utente compila un form i dati immessi dall'utente verso il server viaggiano all'interno del campo body).
Esempio:
HTTP/1.1 200 OK
Connection: close
Date: Thu, 18 Aug 2015 15:44:04 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
Content-length: 6821
Content-type: text/html
(data data data data data …)
Il messaggio è stato volutamente diviso in tre gruppi:
Il corpo è il fulcro del messaggio di risposta HTTP che contiene i dati richiesti.
La prima riga mostra il nome del protocollo e la versione usata (1.1), un codice di stato e un messaggio di stato (OK, il che vuol dire che sta andando tutto bene).Connection: close
, indica che il server vuole chiudere la connessione TCP una volta inviati i dati.Date: …
, indica la data in cui l'oggetto è inviato tramite HTTP
La riga relativa al server indica il nome del web server con la versione del sistema su cui è installato.Last modified: …
, indica l'ultima volta che è stato modificato o creato il file che si sta inviando, informazione utile a fini di caching locale e su server.Content-length
indica la dimensione dei dati che si stanno inviando.Content-type
indica il tipo di dato.
Vediamo il formato generale di un messaggio di riposta HTTP:
Test di invio manuale di una richiesta HTTP via telnet:
La dicitura GET /kurose_ross/interactive/index.php è stata scritta manualmente, tramite essa si richiede un certo oggetto all'host gaia.cs.umass.edu. L'host risponde con il documento richiesto.
Navigazione: