Internet e il Web
Dalla rete che trasporta i pacchetti al protocollo che trasporta le pagine: IP, TCP, HTTP, cookie, cache e DNS
Internet e il Web non sono la stessa cosa. Internet è l'infrastruttura: miliardi di dispositivi collegati da cavi, fibre e onde radio, che si scambiano dati seguendo regole comuni. Il Web è una delle applicazioni che ci girano sopra, come la posta elettronica, lo streaming o le videochiamate.
Per progettare pagine web non serve essere ingegneri di rete, ma capire cosa succede sotto la pagina fa la differenza: spiega perché un sito è lento, perché un'immagine pesante si nota di più su una connessione mobile, perché esistono HTTPS, i cookie e le cache. Il modulo parte dal cavo e arriva, passo dopo passo, fino alla pagina che compare nel browser.
Una rete di reti
I pezzi di Internet
Guardata «dall'interno», Internet è fatta di tre tipi di componenti.
hostI dispositivi finali, detti anche end system: computer, telefoni, server, televisori, sensori. Stanno ai bordi della rete ed eseguono le applicazioni.
collegamentiI mezzi che trasportano i bit: fibra ottica, rame, onde radio, satellite. Ognuno ha una velocità di trasmissione (banda), misurata in bit al secondo.
commutatoriRouter e switch: ricevono i pacchetti di dati e li inoltrano verso la destinazione, un salto alla volta.
Questi pezzi formano tante reti, ognuna gestita da un'organizzazione: la rete di casa, quella dell'università, quella di un operatore mobile, quella di un data center. Internet è letteralmente una rete di reti: reti indipendenti che si collegano tra loro attraverso i fornitori di accesso, gli ISP (Internet Service Provider).
Cos'è un protocollo
Tutta la comunicazione su Internet è governata da protocolli. L'idea è la stessa delle regole che seguiamo parlando con qualcuno: quando chiedi l'ora a uno sconosciuto prima saluti, aspetti che ti risponda, poi fai la domanda. Se lui risponde «non ho tempo», la conversazione prende un'altra strada.
Protocollo: l'insieme di regole che stabilisce il formato e l'ordine dei messaggi scambiati tra due o più entità, e le azioni da compiere quando un messaggio viene inviato o ricevuto.
Esempi di protocolli li incontrerai in tutto il corso: HTTP per il Web, TCP e IP per il trasporto dei dati, Wi-Fi, Ethernet, 4G e 5G per il collegamento fisico. Perché dispositivi di produttori diversi si capiscano, i protocolli devono essere standard pubblici: quelli di Internet sono pubblicati come RFC (Request for Comments) dall'IETF (Internet Engineering Task Force). L'RFC 9110, per esempio, è la definizione ufficiale di HTTP.
Bordo, accesso e nucleo
Ai bordi della rete stanno gli host, che si dividono in due ruoli. I client chiedono servizi: il tuo browser, l'app di un social. I server li forniscono: sono macchine sempre accese, oggi quasi sempre raccolte in grandi data center. Lo stesso computer può fare da client per un'applicazione e da server per un'altra.
La rete di accesso è il «primo tratto» che collega un host al suo primo router, detto edge router. Ne esistono di tre famiglie: residenziali (casa), istituzionali (scuole, aziende) e mobili.
| Tecnologia | Come funziona | Velocità tipiche |
|---|---|---|
| DSL (ADSL, VDSL) | Usa il doppino telefonico esistente fino alla centrale, dove un DSLAM separa voce e dati, che viaggiano su frequenze diverse. | ADSL: 24–52 Mbps in download, 3,5–16 in upload |
| FTTC («fibra misto rame») | Fibra fino all'armadio in strada, rame per gli ultimi metri. | fino a 100–200 Mbps |
| FTTH (fibra fino a casa) | Fibra ottica fino all'appartamento. | 1–10 Gbps |
| Ethernet | Cavo nelle reti aziendali e universitarie, collegato a uno switch. | 100 Mbps, 1 Gbps, 10 Gbps |
| Wi-Fi | Radio verso un access point, a casa o in aula. | da decine di Mbps a oltre 1 Gbps |
| 4G / 5G | Radio verso le antenne dell'operatore mobile. | decine–centinaia di Mbps |
A casa, di solito, un'unica scatola fa quattro mestieri: modem verso l'operatore, router tra la rete di casa e Internet, firewall e access point Wi-Fi. Più avanti vedrai che fa anche un quinto lavoro, il NAT.
Il nucleo (network core) è la maglia di router interconnessi che collega tra loro le reti di accesso. I dati non viaggiano come un flusso continuo: gli host spezzano ogni messaggio in pacchetti, e la rete inoltra ciascun pacchetto da un router all'altro lungo un percorso che va dalla sorgente alla destinazione.
Come si collegano gli ISP
Gli host si collegano a Internet attraverso un ISP di accesso. Ma perché due host qualsiasi, in qualunque parte del mondo, possano scambiarsi pacchetti, anche gli ISP devono essere collegati tra loro. Con milioni di ISP di accesso, collegare ognuno direttamente a tutti gli altri richiederebbe un numero di collegamenti che cresce come il quadrato degli ISP: non è realizzabile.
La struttura reale è nata un pezzo alla volta, spinta soprattutto dall'economia.
- Gli ISP di accesso si collegano a un ISP di transito globale, pagandolo: il primo è il cliente, il secondo il fornitore.
- Se fare l'ISP globale è un buon affare, ne nascono diversi concorrenti, che devono essere collegati tra loro. Si collegano con accordi di peering, spesso senza scambio di denaro, in punti chiamati IXP (Internet eXchange Point).
- Nascono ISP regionali che raccolgono gli ISP di accesso di una zona e li collegano a quelli globali.
- Le grandi aziende di contenuti (Google, Microsoft, Akamai, Meta) costruiscono reti proprie che collegano i loro data center direttamente a molti ISP, scavalcando i livelli intermedi per portare i contenuti più vicino agli utenti.
Al centro di tutto ci sono pochi ISP di primo livello (tier-1), come Lumen, AT&T o NTT, con copertura nazionale e internazionale, che non pagano nessuno per il transito. In Italia gli IXP principali sono il MIX di Milano e il Namex di Roma. Tra i continenti, il traffico corre su cavi sottomarini in fibra ottica.
La distanza fisica è un limite che nessuna banda può eliminare: la luce nella fibra impiega circa 5 millisecondi ogni mille chilometri, e una richiesta deve fare andata e ritorno. Per questo i grandi siti replicano i propri server in data center vicini agli IXP e agli utenti: è l'idea alla base delle CDN (Content Delivery Network), che servono la stessa immagine o lo stesso video da una copia a pochi chilometri da te invece che dall'altra parte dell'oceano.
Pacchetti, code e ritardi
La commutazione di pacchetto
Quando un'applicazione deve spedire un messaggio, l'host lo divide in blocchi più piccoli, i pacchetti, lunghi L bit, e li immette nel collegamento a una velocità di R bit al secondo. Il tempo necessario per «spingere» un pacchetto intero sul cavo si chiama ritardo di trasmissione:
Un pacchetto da 10.000 bit (10 kbit) su un collegamento da 100 Mbps impiega 10.000 / 100.000.000 = 0,0001 secondi, cioè 0,1 millisecondi. Sembra poco, ma un pacchetto attraversa decine di collegamenti prima di arrivare.
Ogni router svolge due funzioni diverse, che è facile confondere.
Inoltro (forwarding)
Un'azione locale e rapidissima: quando arriva un pacchetto, il router legge l'indirizzo di destinazione nell'intestazione, lo cerca nella sua tabella di inoltro e lo manda sul collegamento di uscita giusto.
Instradamento (routing)
Un'azione globale: gli algoritmi di instradamento calcolano i percorsi migliori attraverso la rete e riempiono le tabelle di inoltro dei router.
Un'analogia: l'instradamento è il navigatore che calcola la strada da Pisa a Bologna; l'inoltro è la lettura del cartello a ogni incrocio. Il cartello non conosce l'intero viaggio, sa solo da che parte mandarti adesso.
I router lavorano in modalità store and forward, «memorizza e inoltra»: un pacchetto deve essere arrivato per intero prima di poter essere ritrasmesso sul collegamento successivo. Il router ha bisogno di tutto il pacchetto per controllarne l'intestazione e gli eventuali errori.
Conseguenza: se un pacchetto attraversa N collegamenti tutti alla velocità R, il ritardo di trasmissione si paga N volte, e il tempo complessivo diventa N · L / R.
Code, perdite e circuiti
Che succede se in un router arrivano più pacchetti di quanti il collegamento di uscita riesca a smaltirne? Quelli in eccesso aspettano in una coda in memoria (il buffer). E se la memoria si riempie, i pacchetti successivi vengono scartati: è la perdita di pacchetti, che il livello di trasporto dovrà poi gestire ritrasmettendo.
L'esempio classico: due host collegati a 100 Mbps inviano a un router la cui uscita va a 1,5 Mbps. Finché il traffico è occasionale va tutto bene; se entrambi inviano tanto e insieme, la coda cresce.
La rete telefonica tradizionale funzionava in modo opposto: all'inizio di una chiamata si riservavano le risorse lungo tutto il percorso, un «circuito» dedicato che restava tuo finché non riattaccavi, anche nei momenti di silenzio.
| Commutazione di circuito | Commutazione di pacchetto | |
|---|---|---|
| Risorse | riservate in anticipo, dedicate | condivise, usate solo quando servono |
| Prestazioni | garantite: niente code | variabili: possibili code e perdite |
| Spreco | il circuito resta inutilizzato nei silenzi | nessuno: chi non trasmette non occupa nulla |
| Adatta a | traffico costante (telefonia classica) | traffico «a raffiche», come quello dei computer |
Internet ha scelto i pacchetti perché il traffico dei dati è fatto di raffiche: carichi una pagina, poi la leggi per un minuto senza scaricare nulla. Condividere i collegamenti permette di servire molti più utenti con la stessa infrastruttura.
Le quattro componenti del ritardo
Mentre attraversa un router (un nodo), un pacchetto accumula quattro tipi di ritardo:
d_elabElaborazione: controllare gli errori, leggere l'intestazione, scegliere l'uscita. Di solito sotto il microsecondo.
d_codaCoda: il tempo passato in attesa che il collegamento di uscita si liberi. Dipende dalla congestione: da zero a moltissimo.
d_transTrasmissione: L/R, il tempo per immettere tutti i bit del pacchetto nel collegamento. Dipende dalla banda.
d_propPropagazione: d/s, il tempo che un bit impiega a percorrere il collegamento, lungo d, alla velocità s (circa 2 × 108 m/s). Dipende dalla distanza.
L'analogia della carovana
Trasmissione e propagazione si confondono facilmente. Immagina una carovana di 10 auto che viaggia in autostrada. A ogni casello l'addetto impiega 12 secondi per far passare un'auto; tra un casello e l'altro ci sono 100 km, percorsi a 100 km/h.
- Far passare tutta la carovana da un casello richiede 10 × 12 s = 2 minuti: è la trasmissione (le auto sono i bit, il casello è il router).
- Percorrere i 100 km fino al casello successivo richiede 1 ora: è la propagazione.
Un casello più veloce riduce il primo tempo, ma non il secondo: solo una strada più corta riduce la propagazione. Prova i due effetti con il calcolatore.
Con i valori di partenza la propagazione domina; se scegli il collegamento da 1,5 Mbps e il pacchetto da 1 Mbit, domina la trasmissione. Con il collegamento Pisa–New York la propagazione da sola vale 34 ms per ogni viaggio di sola andata, qualunque sia la banda.
Quando la coda esplode
Il ritardo di coda dipende dall'intensità di traffico: il rapporto tra i bit che arrivano e quelli che il collegamento può smaltire.
dove a è il numero medio di pacchetti che arrivano al secondo. Se l'intensità è vicina a 0, la coda è quasi sempre vuota; se si avvicina a 1, il ritardo cresce molto rapidamente; se supera 1, arriva più lavoro di quello che si riesce a servire e la coda cresce senza limite.
Ritardi veri: traceroute
Il programma traceroute misura i ritardi reali lungo un percorso. Invia verso la destinazione tre pacchetti per ogni router intermedio, costruiti in modo che il router numero i li scarti e risponda al mittente (si imposta a i il campo time-to-live del pacchetto). Il mittente misura quanto tempo passa tra l'invio e la risposta.
traceroute: gaia.cs.umass.edu → www.eurecom.fr 1 cs-gw (128.119.240.254) 1 ms 1 ms 2 ms 2 border1-rt-fa5-1-0.gw.umass.edu 1 ms 1 ms 2 ms … 7 nycm-wash.abilene.ucaid.edu 22 ms 22 ms 22 ms 8 62.40.103.253 104 ms 109 ms 106 ms ← collegamento transoceanico 9 de2-1.de1.de.geant.net 109 ms 102 ms 104 ms 10 de.fr1.fr.geant.net 113 ms 121 ms 114 ms … 17 * * * ← il router non risponde 19 fantasia.eurecom.fr 132 ms 128 ms 136 ms
Tre cose da notare. Il salto tra il router 7 e l'8 costa 80 ms: è l'attraversamento dell'Atlantico, pura propagazione. A volte un ritardo diminuisce da un router al successivo: le misure sono indipendenti e la coda cambia di istante in istante. Gli asterischi indicano router che non rispondono o sonde perse.
Provalo. Dal terminale: traceroute www.unipi.it su macOS e Linux, tracert www.unipi.it sul prompt dei comandi di Windows.
Indirizzi IP e NAT
Indirizzi, blocchi e prefissi
Per consegnare un pacchetto serve un indirizzo. Nella versione 4 del protocollo IP, IPv4, un indirizzo è un numero di 32 bit associato non all'host in sé, ma a una sua interfaccia: il punto di collegamento tra il dispositivo e un collegamento fisico. Un portatile ha di solito due interfacce (Wi-Fi ed Ethernet), un router molte.
Per leggerli comodamente, i 32 bit si dividono in quattro gruppi da 8 (ottetti) e ciascuno si scrive in decimale, separato da un punto: è la notazione decimale puntata.
223.1.1.1 = 11011111 00000001 00000001 00000001
└ 223 ┘ └ 1 ┘ └ 1 ┘ └ 1 ┘
Ogni ottetto va quindi da 0 a 255. Ripassa la conversione binario-decimale nel modulo sulla rappresentazione dell'informazione.
Gli indirizzi non si assegnano uno per uno, ma a blocchi contigui. Un blocco si descrive con un prefisso e la notazione /n (CIDR): i primi n bit identificano la rete e sono uguali per tutti gli indirizzi del blocco, i restanti si possono assegnare liberamente.
Un ISP che possiede il blocco 200.23.16.0/20 ha 32 − 20 = 12 bit liberi, cioè 4.096 indirizzi. Può dividerlo in 8 blocchi /23 da 512 indirizzi, uno per ogni organizzazione cliente:
| Blocco | Bit (in evidenza il prefisso) | Notazione |
|---|---|---|
| ISP | 11001000 00010111 00010000 00000000 | 200.23.16.0/20 |
| Organizzazione 0 | 11001000 00010111 00010000 00000000 | 200.23.16.0/23 |
| Organizzazione 1 | 11001000 00010111 00010010 00000000 | 200.23.18.0/23 |
| Organizzazione 2 | 11001000 00010111 00010100 00000000 | 200.23.20.0/23 |
| … | … | … |
| Organizzazione 7 | 11001000 00010111 00011110 00000000 | 200.23.30.0/23 |
Al vertice c'è l'ICANN (Internet Corporation for Assigned Names and Numbers), che distribuisce i blocchi a cinque registri regionali (per l'Europa il RIPE NCC), che a loro volta li assegnano agli ISP. L'ICANN gestisce anche la radice del sistema dei nomi, il DNS.
Con 32 bit si ottengono circa 4,3 miliardi di indirizzi: meno degli abitanti della Terra, e molti meno dei dispositivi connessi. Nel 2011 l'ICANN ha assegnato gli ultimi blocchi IPv4 liberi. Le risposte sono due:
- il NAT, che permette a un'intera rete di condividere un solo indirizzo pubblico;
- IPv6, con indirizzi da 128 bit scritti in esadecimale, come
2001:db8::8a2e:370:7334: circa 3,4 × 1038 indirizzi, abbastanza per non porsi più il problema.
La tabella di inoltro: il prefisso più lungo
Un router non può avere una riga per ogni indirizzo del mondo: la tabella di inoltro contiene intervalli di indirizzi, espressi come prefissi. Ma gli intervalli possono sovrapporsi: un indirizzo può corrispondere a più righe. La regola per scegliere è il longest prefix matching: si usa la riga con il prefisso più lungo che corrisponde all'indirizzo, cioè la più specifica.
Prova con gli indirizzi degli esempi, o scrivine uno tuo in binario o in decimale puntato.
Nel secondo esempio l'indirizzo corrisponde sia alla riga 1 (24 bit) sia alla riga 2 (21 bit): vince la riga 1, più lunga. È come cercare una via: se hai l'indicazione per «via Diotisalvi», vale più di quella per «Pisa».
Il NAT: tante case, un indirizzo
Dentro la rete di casa i dispositivi usano indirizzi privati, presi da tre intervalli riservati che non esistono su Internet e che chiunque può riutilizzare:
10.0.0.0/8172.16.0.0/12192.168.0.0/16(quello che trovi quasi sempre nei router di casa:192.168.1.x)
Verso l'esterno, invece, tutti i dispositivi appaiono con un solo indirizzo pubblico, quello del router. Il meccanismo che lo rende possibile si chiama NAT (Network Address Translation) e porta diversi vantaggi:
- all'ISP basta assegnare un indirizzo pubblico per un'intera casa o azienda;
- puoi cambiare gli indirizzi interni senza avvisare nessuno fuori;
- puoi cambiare ISP senza toccare la rete di casa;
- i dispositivi interni non sono raggiungibili direttamente dall'esterno: un livello di protezione in più.
Il router NAT tiene una tabella di traduzione. Per ogni datagramma in uscita sostituisce l'indirizzo e la porta di origine privati con il proprio indirizzo pubblico e una porta nuova, e annota la corrispondenza; per ogni datagramma in entrata fa l'operazione inversa. Segui i quattro passi:
Il NAT ha anche un costo: rompe il principio per cui ogni host è raggiungibile direttamente. Per ospitare un server dietro un NAT bisogna configurare a mano l'inoltro delle porte (port forwarding).
Livelli, applicazioni e trasporto
La pila dei protocolli
Una rete è un sistema enormemente complesso: host, router, mezzi fisici diversi, applicazioni, hardware, software. Il modo per non perdersi è la stratificazione: dividere il problema in livelli, dove ogni livello offre un servizio a quello superiore e usa il servizio di quello inferiore.
Un viaggio in aereo funziona allo stesso modo: biglietto, bagaglio, imbarco, decollo, rotta, e poi a ritroso atterraggio, sbarco, ritiro bagagli, reclamo sul biglietto. Chi si occupa dei bagagli non ha bisogno di sapere come si pilota. Il vantaggio concreto è la modularità: si può cambiare l'implementazione di un livello, per esempio passare dal cavo al Wi-Fi, senza toccare gli altri.
La pila di Internet ha cinque livelli, dall'applicazione fino ai bit sul cavo:
| Livello | Cosa fa | Protocolli | Unità di dati |
|---|---|---|---|
| 5. Applicazione | Supporta le applicazioni di rete | HTTP, SMTP, IMAP, DNS | messaggio |
| 4. Trasporto | Trasferisce dati da processo a processo | TCP, UDP | segmento |
| 3. Rete | Instrada i pacchetti dalla sorgente alla destinazione | IP, protocolli di instradamento | datagramma |
| 2. Collegamento | Trasferisce dati tra nodi vicini | Ethernet, Wi-Fi (802.11) | frame |
| 1. Fisico | Trasmette i singoli bit sul mezzo | dipende dal mezzo | bit |
Esiste anche un modello di riferimento a sette livelli, l'ISO/OSI, che aggiunge sessione e presentazione tra trasporto e applicazione. È utile come vocabolario («un problema di livello 2»), ma Internet è costruita sulla pila a cinque.
L'incapsulamento
Scendendo la pila, ogni livello prende i dati del livello superiore e ci aggiunge davanti la propria intestazione (header), con le informazioni che servono al suo lavoro. È come una matrioska: il messaggio finisce dentro un segmento, il segmento dentro un datagramma, il datagramma dentro un frame. A destinazione si fa il percorso inverso, e ogni livello toglie l'intestazione del livello «pari» del mittente.
I router intermedi arrivano solo fino al livello di rete (leggono l'intestazione IP per decidere dove inoltrare), gli switch solo fino al livello di collegamento. Solo gli host usano tutti e cinque i livelli.
Client-server e peer-to-peer
Scrivere un'applicazione di rete significa scrivere programmi che girano sugli host e comunicano attraverso la rete, per esempio un browser e un web server. Non serve scrivere nulla per i router: il nucleo della rete non esegue applicazioni degli utenti, ed è proprio questo che ha permesso al Web di diffondersi così in fretta.
| Client-server | Peer-to-peer (P2P) | |
|---|---|---|
| Chi fornisce il servizio | un server sempre acceso, spesso in un data center | gli stessi utenti, che si scambiano servizi |
| Indirizzo | il server ha un indirizzo IP fisso; i client possono averlo dinamico | i peer si connettono a intermittenza e cambiano indirizzo |
| Comunicazione | i client parlano solo con il server, non tra loro | i peer comunicano direttamente |
| Scalabilità | servono più server per più client | ogni nuovo peer porta anche nuova capacità |
| Esempi | Web (HTTP), posta (IMAP), FTP | BitTorrent |
Processi, socket e porte
A comunicare, in realtà, non sono gli host ma i processi: i programmi in esecuzione. Il processo che inizia la comunicazione è il client, quello che aspetta di essere contattato è il server.
Un processo invia e riceve messaggi attraverso un socket, che funziona come una porta di casa: il processo «spinge fuori» il messaggio dalla porta e si affida all'infrastruttura di trasporto dall'altra parte perché arrivi al socket del destinatario. Il socket è il confine tra ciò che controlla il programmatore dell'applicazione e ciò che controlla il sistema operativo.
L'indirizzo IP identifica l'host, ma su un host girano molti processi: il browser, il client di posta, Spotify. Per individuare il processo giusto serve anche un numero di porta, un numero a 16 bit associato al socket. Un processo si identifica quindi con la coppia indirizzo IP + porta.
| Porta | Servizio |
|---|---|
80 | HTTP, il Web senza cifratura |
443 | HTTPS, il Web cifrato |
25 | SMTP, invio della posta tra server |
53 | DNS, risoluzione dei nomi |
22 | SSH, terminale remoto sicuro |
3306 | MySQL, il database del corso di Basi di Dati |
Per mandare una richiesta al server web dell'Università di Pisa servono quindi il suo indirizzo IP (nelle slide del corso: 131.114.104.6) e la porta 80, o 443 se la connessione è cifrata. Le porte sotto la 1024 sono «ben note» e riservate ai servizi standard; i client usano porte alte scelte a caso dal sistema operativo.
TCP e UDP
Internet offre alle applicazioni due servizi di trasporto.
TCP
- affidabile: i dati arrivano tutti, in ordine;
- controllo di flusso: non travolge un destinatario lento;
- controllo della congestione: rallenta quando la rete è sovraccarica;
- orientato alla connessione: client e server si accordano prima di iniziare.
Non garantisce tempi, banda minima né sicurezza.
UDP
- non affidabile: i dati possono perdersi o arrivare in disordine;
- nessun controllo di flusso o di congestione;
- nessuna connessione da stabilire.
Perché esiste, allora? Perché è leggero e immediato: niente attesa per aprire la connessione, niente rallentamenti imposti. Per una chiamata è meglio perdere un frammento di voce che riceverlo in ritardo; per il DNS basta un messaggio e una risposta.
Ecco quale trasporto usano le applicazioni più comuni:
| Applicazione | Protocollo applicativo | Trasporto |
|---|---|---|
| trasferimento di file | FTP (RFC 959) | TCP |
| posta elettronica | SMTP (RFC 5321) | TCP |
| Web | HTTP/1.1 e HTTP/2 (RFC 9110) | TCP |
| Web | HTTP/3 | QUIC su UDP |
| telefonia su Internet | SIP, RTP o proprietari | TCP o UDP |
| streaming | HTTP, DASH | TCP |
| giochi interattivi | proprietari | UDP o TCP |
Sul tuo computer arrivano insieme i dati del browser, di Netflix e di una videochiamata. Come fa il livello di trasporto a consegnare ogni segmento al processo giusto? Grazie ai numeri di porta scritti nell'intestazione di ogni segmento.
- Multiplexing (al mittente): il trasporto raccoglie i dati dai diversi socket e aggiunge a ciascuno un'intestazione con porta di origine e di destinazione.
- Demultiplexing (al destinatario): il trasporto legge le porte e consegna ogni segmento al socket giusto.
UDP distingue i socket solo con la porta di destinazione. TCP usa una quaterna: indirizzo IP e porta di origine, indirizzo IP e porta di destinazione. È così che un server web sulla porta 443 tiene separate migliaia di connessioni contemporanee: la porta di destinazione è sempre 443, ma ogni client ha un indirizzo o una porta di origine diversi.
Rendere sicuro TCP: TLS
TCP e UDP, da soli, non cifrano nulla: una password scritta in un socket normale attraversa Internet in chiaro, leggibile da chiunque intercetti il traffico. Per questo esiste TLS (Transport Layer Security), che sopra TCP aggiunge tre garanzie:
- cifratura: nessuno lungo il percorso può leggere i dati;
- integrità: nessuno può modificarli senza che ce ne si accorga;
- autenticazione: sei sicuro di parlare con il server vero, grazie ai certificati digitali.
TLS è implementato come libreria al livello di applicazione: l'applicazione scrive in chiaro nel «socket» TLS, e i dati viaggiano cifrati. HTTPS è semplicemente HTTP su TLS: il lucchetto accanto all'indirizzo nel browser indica proprio una connessione TLS verificata.
Il Web
Com'è nato il Web
Il World Wide Web nasce al CERN di Ginevra, il laboratorio europeo di fisica delle particelle. Nel 1989 l'informatico inglese Tim Berners-Lee propone un sistema per condividere documenti tra i ricercatori; nel 1990, insieme al belga Robert Cailliau, ne pubblica la versione formale: un sistema di ipertesti, documenti che contengono collegamenti ad altri documenti, anche su computer diversi. Il primo sito web va online alla fine del 1990 e diventa pubblico nel 1991.
Nel giro di pochi mesi Berners-Lee costruisce tutti i pezzi che usiamo ancora oggi:
- l'URL, per identificare e trovare in modo univoco ogni risorsa del Web;
- il protocollo HTTP, che descrive come funzionano richieste e risposte;
- il linguaggio HTML, per scrivere i documenti;
- un programma che risponde alle richieste HTTP: il web server;
- un programma che fa richieste HTTP a partire da un URL e mostra l'HTML che riceve: il browser.
Nel 1993 il CERN decide di non brevettare il Web e di renderne pubblici protocolli e codice, senza diritti da pagare: è la ragione principale della sua diffusione esplosiva. Nel 1994 Berners-Lee fonda il W3C (World Wide Web Consortium), l'organizzazione internazionale che da allora cura gli standard del Web, come CSS e l'accessibilità.
Siti statici e dinamici
Nei primi anni per creare un sito bastava conoscere l'HTML e saper preparare qualche immagine. Un sito statico è fatto solo di file già pronti sul server: ogni utente, in ogni momento, riceve esattamente la stessa pagina. Il server si limita a leggere il file richiesto e a spedirlo.
In pochi anni i siti diventano più ambiziosi: su molti server girano programmi che generano le pagine al momento. Leggono dati da un database, parlano con altri sistemi (una banca, un magazzino) e producono l'HTML da rimandare al browser. Questo è un sito dinamico: il contenuto nasce durante la richiesta e può cambiare da utente a utente. Il tuo carrello, la tua casella di posta, la home di un social sono pagine dinamiche.
Lato client
Codice che gira nel browser dell'utente: HTML, CSS e JavaScript. Può reagire ai clic senza ricaricare la pagina, ma non vede il database e chiunque può leggerlo.
Lato server
Codice che gira sul server: PHP, Python, Java, JavaScript con Node.js. Accede ai dati, controlla password e permessi. L'utente vede solo l'HTML che ne esce.
Nella sua essenza, un web server non è altro che un programma che risponde a richieste HTTP. Per mettere in piedi un sito dinamico serve però un intero stack (una «pila» di software): un sistema operativo, il web server, un database e un linguaggio con cui scrivere le pagine dinamiche.
| Stack | Sistema operativo | Web server | Database | Linguaggio |
|---|---|---|---|---|
| LAMP | Linux | Apache | MySQL | PHP |
| WISA | Windows | IIS | SQL Server | ASP.NET |
| MEAN | qualsiasi | Node.js con Express | MongoDB | JavaScript (Angular nel browser) |
Gli URL
Ogni risorsa del Web (una pagina, un'immagine, un video) ha un indirizzo: l'URL, Uniform Resource Locator. Un URL dice come ottenere la risorsa (lo schema), da chi (l'host e la porta) e dove si trova sul server (il percorso), più eventuali parametri e una posizione nella pagina.
Il frammento resta nel browser. La parte dopo # non viaggia mai nella richiesta HTTP: il server riceve /didattica/corsi.html?anno=2026&lingua=it e basta. È il browser, una volta ricevuta la pagina, a scorrere fino all'elemento con id="orari".
Capiterà di leggere anche URI (Uniform Resource Identifier): è la categoria generale di tutti gli identificatori di risorse. Un URL è un URI che dice anche dove trovare la risorsa. Un URN (Uniform Resource Name) è invece un nome permanente che non dice dove sta la risorsa, come urn:isbn:0451450523, che identifica un libro attraverso il suo codice ISBN. Nella pratica del Web si usano quasi solo URL, e i due termini vengono spesso usati come sinonimi.
Gli schemi che incontrerai più spesso:
| Schema | Esempio | Cosa fa |
|---|---|---|
https: | https://www.unipi.it/ | pagina web su connessione cifrata (porta 443) |
http: | http://localhost:8000/ | pagina web senza cifratura (porta 80); oggi da usare solo in locale |
mailto: | mailto:segreteria@unipi.it | apre il programma di posta con il destinatario già compilato |
tel: | tel:+390502212111 | sul telefono avvia la chiamata |
file: | file:///Users/mario/sito/index.html | un file sul tuo computer: nessuna richiesta di rete |
data: | data:image/svg+xml,… | il contenuto è scritto direttamente dentro l'URL |
Un URL può contenere solo un insieme limitato di caratteri. Spazi, lettere accentate e simboli riservati come ?, &, # o / usati fuori dal loro ruolo vanno codificati: si scrive % seguito dal valore esadecimale dei byte del carattere in UTF-8.
| Carattere | Codificato | Esempio |
|---|---|---|
| spazio | %20 (nelle query anche +) | ?q=progettazione%20web |
& | %26 | ?azienda=Rossi%26Figli |
/ | %2F | ?data=28%2F09%2F2026 |
è | %C3%A8 (due byte in UTF-8) | /citt%C3%A0 per «città» |
Di solito non devi farlo a mano: il browser codifica da solo quello che scrivi nella barra degli indirizzi e i dati dei moduli. Ma quando un link «non funziona» per colpa di uno spazio nel nome di un file, il motivo è questo. Regola pratica: nomi di file in minuscolo, senza spazi né accenti, con i trattini al posto degli spazi (chi-siamo.html).
Nomi di dominio
La parte host di un URL, come www.unipi.it, è un nome di dominio e si legge da destra a sinistra, dal generale al particolare:
itè il dominio di primo livello (TLD, Top-Level Domain): può essere nazionale (.it,.fr,.jp) o generico (.com,.org,.edu);unipiè il dominio di secondo livello, quello che un'organizzazione registra;wwwè un nome scelto dall'organizzazione dentro il proprio dominio, comeesami.unipi.itomail.unipi.it.
Una curiosità a chilometro zero: il Registro .it, che gestisce tutti i domini italiani, ha sede a Pisa, all'Istituto di Informatica e Telematica del CNR. E il primo collegamento italiano a Internet, nel 1986, partì proprio da Pisa, dal centro CNUCE del CNR.
Una pagina è fatta di oggetti
Una pagina web non è un unico file. È un file HTML di base che fa riferimento a molti altri oggetti: fogli di stile, immagini, script, font, video. Ognuno ha il suo URL e può trovarsi anche su un server diverso. Il browser scarica prima l'HTML, lo legge, scopre gli oggetti a cui rimanda e li richiede uno per uno.
<!-- www.someschool.edu/someDept/home.html: il file di base --> <link rel="stylesheet" href="stile.css"> <!-- oggetto 1 --> <img src="pic.gif" alt="Logo del dipartimento"> <!-- oggetto 2 --> <img src="https://cdn.esempio.it/foto.jpg" alt="Aula"> <!-- oggetto 3, su un altro server --> <script src="menu.js"></script> <!-- oggetto 4 -->
Una pagina tipica di un grande sito richiede decine, a volte centinaia, di oggetti. È per questo che il modo in cui HTTP gestisce le connessioni conta tanto per la velocità, come vedrai tra poco.
Provalo. Apri gli strumenti per sviluppatori del browser (F12, oppure Cmd + Option + I su Mac), scegli la scheda Rete (Network) e ricarica una pagina: vedrai l'elenco di tutti gli oggetti scaricati, con dimensione, tipo e tempo di ciascuno.
Il protocollo HTTP
Client, server e nessuna memoria
HTTP (HyperText Transfer Protocol) è il protocollo del livello di applicazione del Web. Segue il modello client-server: il client è il browser, che chiede gli oggetti, li riceve e li mostra; il server è il web server, che manda gli oggetti in risposta alle richieste. Safari su un iPhone, Firefox su un PC e Chrome su un tablet parlano tutti con lo stesso server Apache perché usano tutti HTTP.
HTTP usa TCP come trasporto:
- il client apre una connessione TCP (crea un socket) verso il server, sulla porta 80, o 443 con HTTPS;
- il server accetta la connessione;
- browser e server si scambiano messaggi HTTP;
- la connessione TCP viene chiusa.
HTTP è stateless, «senza stato»: il server non conserva alcuna informazione sulle richieste precedenti di un client. Se chiedi la stessa pagina due volte di fila, il server risponde due volte da capo, senza sapere che eri già passato.
È una scelta voluta. I protocolli che mantengono uno stato sono complicati: devono ricordare la storia passata, e se il client o il server si bloccano, le due parti possono ritrovarsi con versioni incoerenti di quello stato, da riconciliare. Senza stato, ogni richiesta sta in piedi da sola. Quando uno stato serve davvero, per esempio per sapere chi ha fatto login, lo si aggiunge sopra con i cookie.
Connessioni e tempi di risposta
HTTP non persistente
- si apre una connessione TCP;
- si invia al massimo un oggetto;
- si chiude la connessione.
Per scaricare più oggetti servono più connessioni. È il comportamento di HTTP/1.0.
HTTP persistente
- si apre una connessione TCP verso il server;
- si inviano più oggetti sulla stessa connessione;
- la connessione si chiude dopo un po' di inattività.
È il comportamento predefinito da HTTP/1.1 in poi.
Un esempio. Scrivi www.someSchool.edu/someDepartment/home.index, una pagina di testo con riferimenti a 10 immagini JPEG. Con HTTP non persistente succede questo:
- il client apre una connessione TCP verso il processo server di
www.someSchool.edu, porta 80; il server, in attesa su quella porta, la accetta e lo comunica al client; - il client invia nel socket il messaggio di richiesta, che indica l'oggetto
someDepartment/home.index; - il server riceve la richiesta, prepara il messaggio di risposta con l'oggetto e lo invia nel suo socket;
- il server chiude la connessione TCP;
- il client riceve la risposta con il file HTML, lo mostra, lo analizza e trova i 10 riferimenti alle immagini;
- i passi da 1 a 5 si ripetono per ognuna delle 10 immagini.
Per stimare quanto costa tutto questo si usa l'RTT (Round-Trip Time): il tempo che un pacchetto piccolo impiega ad andare dal client al server e tornare indietro. Con HTTP non persistente, ogni oggetto richiede:
- un RTT per aprire la connessione TCP;
- un RTT perché la richiesta HTTP arrivi e tornino i primi byte della risposta;
- il tempo di trasmissione del file.
Facciamo i conti con RTT = 50 ms e oggetti che si trasmettono in 10 ms ciascuno. Per la pagina con 10 immagini:
- non persistente, una connessione alla volta: 11 oggetti × (2 × 50 + 10) ms = 1.210 ms;
- persistente: un RTT per aprire la connessione, poi un RTT e 10 ms per ogni oggetto: 50 + 11 × 60 = 710 ms;
- persistente con richieste in fila (le 10 immagini chieste tutte insieme appena letto l'HTML): 50 + 60 per l'HTML + 50 + 10 × 10 per le immagini = 260 ms.
I problemi dell'HTTP non persistente sono quindi due RTT per ogni oggetto e il lavoro in più per il sistema operativo a ogni nuova connessione. Per compensare, i browser aprono spesso più connessioni in parallelo. HTTP/1.1 rende la connessione persistente per impostazione predefinita: il server la lascia aperta dopo aver risposto, e il client invia una nuova richiesta appena incontra un oggetto, con un tempo complessivo che può scendere fino a un solo RTT per tutti gli oggetti.
I messaggi HTTP
I messaggi HTTP sono di due tipi, richiesta e risposta, e in HTTP/1.1 sono scritti in testo ASCII leggibile. Ogni riga termina con due caratteri invisibili: carriage return e line feed, scritti \r\n. Una riga vuota segna la fine delle intestazioni. Esplora gli scambi qui sotto e clicca su una riga per sapere cosa significa.
Tutti i messaggi di richiesta hanno la stessa struttura:
metodo␣URL␣versione\r\n ← riga di richiesta nome-intestazione: valore\r\n ← righe di intestazione nome-intestazione: valore\r\n (quante ne servono) \r\n ← riga vuota: fine delle intestazioni corpo del messaggio ← facoltativo (per esempio i dati di un POST)
La risposta ha la stessa forma, con al posto della riga di richiesta la riga di stato: versione␣codice␣frase, come HTTP/1.1 200 OK.
I metodi
Il metodo, all'inizio della richiesta, dice che cosa si vuole fare con la risorsa.
| Metodo | Cosa chiede | Sicuro | Idempotente |
|---|---|---|---|
GET | ottenere la risorsa; eventuali dati viaggiano nell'URL, dopo il ? | sì | sì |
HEAD | solo le intestazioni che si otterrebbero con un GET, senza il corpo: utile per sapere se una risorsa esiste o quanto pesa | sì | sì |
POST | inviare dati al server perché li elabori, nel corpo della richiesta: un modulo, un commento, un ordine | no | no |
PUT | caricare un oggetto all'URL indicato, sostituendo completamente quello che c'era | no | sì |
DELETE | cancellare la risorsa | no | sì |
PATCH | modificare solo una parte della risorsa | no | no |
OPTIONS | quali metodi supporta il server per quella risorsa | sì | sì |
Due proprietà da conoscere. Un metodo è sicuro se non modifica nulla sul server: puoi ripeterlo quanto vuoi senza conseguenze, ed è per questo che i motori di ricerca seguono solo i link (che fanno GET). È idempotente se ripeterlo più volte ha lo stesso effetto che farlo una volta: cancellare due volte lo stesso file lo lascia cancellato, ma inviare due volte un ordine con POST crea due ordini. È il motivo per cui il browser ti chiede conferma quando ricarichi una pagina ottenuta con un POST.
Un modulo HTML sceglie il metodo con l'attributo method. Con GET i dati finiscono nell'URL come stringa di query, con chiavi, valori e delimitatori; con POST viaggiano nel corpo del messaggio. Prova a inviare i due moduli: l'anteprima non spedisce nulla, ma ti mostra cosa partirebbe.
Con GET l'indirizzo diventa /cerca?q=progettazione+web: si può salvare nei preferiti e condividere, ed è giusto così per una ricerca. Una password in un GET, invece, resterebbe scritta nella cronologia, nei log del server e nei preferiti: i dati riservati vanno sempre con POST, e su HTTPS.
I codici di stato
La prima riga della risposta contiene un codice di stato a tre cifre. La prima cifra dice la categoria, e basta quella per capire a grandi linee cosa è successo.
| Codice | Significato | Quando lo vedi |
|---|---|---|
| 1xx | Informativi: la richiesta è stata ricevuta, si continua. | |
| 200 | OK | richiesta riuscita, l'oggetto è nel corpo della risposta |
| 301 | Moved Permanently | l'oggetto si è spostato per sempre; il nuovo indirizzo è nell'intestazione Location |
| 302 303 | Found, See Other | spostamento temporaneo, o «vai a vedere lì» dopo un POST |
| 304 | Not Modified | la copia in cache è ancora valida: nessun corpo |
| 400 | Bad Request | il server non ha capito il messaggio di richiesta |
| 401 | Unauthorized | serve autenticarsi |
| 403 | Forbidden | sei riconosciuto, ma non hai il permesso |
| 404 | Not Found | il documento richiesto non esiste su questo server |
| 500 | Internal Server Error | il programma sul server è andato in errore |
| 503 | Service Unavailable | server sovraccarico o in manutenzione |
| 505 | HTTP Version Not Supported | il server non supporta la versione di HTTP della richiesta |
La regola da ricordare: 2xx tutto bene, 3xx vai altrove, 4xx hai sbagliato tu (il client), 5xx ha sbagliato il server.
Intestazioni e tipi MIME
| Intestazione | Dove | A cosa serve |
|---|---|---|
Host | richiesta | il nome del sito; obbligatoria in HTTP/1.1 |
User-Agent | richiesta | browser e sistema operativo del client |
Cookie | richiesta | i cookie che il browser rimanda al sito |
Referer | richiesta | la pagina da cui arriva l'utente (sì, con una sola «r»: un errore di battitura rimasto nello standard) |
Content-Type | entrambe | il tipo MIME del corpo |
Content-Length | entrambe | la lunghezza del corpo in byte |
Location | risposta | dove andare, con i codici 3xx |
Set-Cookie | risposta | consegna un cookie al browser |
Cache-Control | risposta | se e per quanto l'oggetto si può tenere in cache |
Il valore di Content-Type è un tipo MIME, nella forma tipo/sottotipo. È così che il browser sa se deve mostrare una pagina, applicare uno stile, visualizzare un'immagine o proporre un download. Se un server manda un file CSS dichiarandolo text/plain, il browser si rifiuta di applicarlo.
| Tipo MIME | Contenuto | Estensione tipica |
|---|---|---|
text/html | pagina HTML | .html |
text/css | foglio di stile | .css |
text/javascript | script | .js |
image/png, image/jpeg, image/webp, image/avif | immagini raster | .png, .jpg, .webp, .avif |
image/svg+xml | immagine vettoriale | .svg |
application/json | dati strutturati | .json |
application/pdf | documento PDF | .pdf |
Provalo dal terminale. Il comando curl -I https://www.unipi.it manda una richiesta HEAD e stampa la riga di stato e le intestazioni della risposta. Con curl -v vedi anche la richiesta che parte.
Cookie e cache
I cookie
HTTP non ricorda nulla, ma un sito ha bisogno di sapere che la richiesta di adesso arriva dalla stessa persona che un minuto fa ha messo un libro nel carrello. La soluzione sono i cookie: piccoli dati che il sito affida al browser e che il browser gli rimanda a ogni richiesta. Il meccanismo ha quattro componenti:
- un'intestazione
Set-Cookienella risposta HTTP; - un'intestazione
Cookienelle richieste successive; - un file dei cookie sul computer dell'utente, gestito dal browser;
- un database sul server del sito.
Susan usa il portatile e visita per la prima volta un sito di e-commerce. Quando la prima richiesta arriva, il sito crea un identificativo univoco (il cookie, per esempio 1678) e una riga nel proprio database associata a quell'identificativo. Ogni richiesta successiva di Susan conterrà il valore 1678, e il sito potrà «riconoscerla».
Com'è fatto un cookie
Nella realtà un cookie ha un nome, un valore e una serie di attributi che ne regolano la vita e la sicurezza:
Set-Cookie: sessione=8f3a2c; Max-Age=3600; Path=/; Secure; HttpOnly; SameSite=Lax
| Attributo | Effetto |
|---|---|
Expires / Max-Age | la scadenza, come data o in secondi. Senza, è un cookie di sessione che sparisce alla chiusura del browser; con, è un cookie persistente. |
Domain, Path | per quali indirizzi il browser deve rimandarlo. |
Secure | viaggia solo su HTTPS. |
HttpOnly | JavaScript non può leggerlo: uno script malevolo iniettato nella pagina non può rubare la sessione. |
SameSite | Strict, Lax o None: se inviarlo anche quando la richiesta parte da un altro sito. Protegge da attacchi in cui un sito ostile ti fa compiere azioni a tua insaputa. |
I cookie servono per carrelli, raccomandazioni, e soprattutto per lo stato della sessione: quando accedi alla webmail, è un cookie a tenerti collegato mentre passi da un messaggio all'altro. Il browser ne tiene uno spazio limitato, circa 4 KB per cookie: dentro c'è di solito solo un identificativo, e i dati veri stanno nel database del sito.
Terze parti e GDPR
Una pagina di nytimes.com contiene spesso pubblicità servite da un'altra azienda, per esempio AdX.com. Per mostrarle, il browser fa una richiesta anche ad AdX, che può impostare un suo cookie. Così nascono due tipi di cookie:
- di prima parte: impostati dal sito che hai scelto di visitare, quello che fornisce il file HTML di base;
- di terza parte: impostati da un sito che non hai scelto di visitare, ma i cui contenuti sono incorporati nella pagina.
I cookie di prima parte permettono di tracciare il comportamento dell'utente su un sito. I cookie di terza parte permettono di tracciarlo attraverso molti siti, senza che l'utente abbia mai scelto di visitare il sito che traccia. Per questo Safari e Firefox oggi bloccano o isolano i cookie di terza parte per impostazione predefinita.
In Europa il GDPR (General Data Protection Regulation, in vigore da maggio 2018) considera i cookie capaci di identificare una persona come dati personali. Il considerando 30 lo dice esplicitamente: indirizzi IP e identificativi dei cookie lasciano tracce che, combinate con altre informazioni, possono servire a creare profili delle persone e a identificarle.
La conseguenza pratica sono i banner che vedi su quasi ogni sito: l'utente deve avere un controllo esplicito sui cookie. In Italia le linee guida del Garante (2021) distinguono:
- cookie tecnici (sessione, carrello, lingua scelta): non richiedono consenso, basta informare;
- cookie di profilazione e di terze parti per la pubblicità: richiedono il consenso preventivo, e rifiutare deve essere facile quanto accettare. Chiudere il banner con la X equivale a rifiutare.
Le web cache
Una web cache, detta anche proxy server, ha un obiettivo: soddisfare le richieste dei client senza disturbare il server di origine. Il browser manda tutte le richieste alla cache:
- se l'oggetto è in cache, la cache lo restituisce subito;
- altrimenti lo chiede al server di origine, ne tiene una copia e poi lo restituisce al client.
La cache è quindi client e server allo stesso tempo: fa da server per il browser che le chiede l'oggetto e da client verso il server di origine. Di solito la installa un ISP, un'università o un'azienda. Perché conviene?
- riduce il tempo di risposta, perché la cache è più vicina al client;
- riduce il traffico sul collegamento d'accesso di un'organizzazione;
- Internet è piena di cache, e questo permette anche ai fornitori di contenuti «poveri», con server modesti, di servire molti utenti.
È il server a dire, nelle intestazioni della risposta, se e per quanto un oggetto si può tenere in cache.
Un'istituzione ha una rete interna da 1 Gbps e un collegamento d'accesso a Internet da 1,54 Mbps. Gli oggetti pesano in media 100 kbit, i browser ne chiedono 15 al secondo: in totale 1,5 Mbps. L'RTT dal router dell'istituzione ai server è di 2 secondi.
L'utilizzo del collegamento d'accesso è 1,5 / 1,54 = 0,97: come hai visto parlando di intensità di traffico, a questo livello le code diventano enormi, e il ritardo totale è 2 secondi + minuti + microsecondi. Ci sono due soluzioni:
- comprare un collegamento più veloce, da 154 Mbps: l'utilizzo scende a 0,0097, il ritardo a 2 secondi e qualche millisecondo. Ma costa moltissimo;
- installare una cache, che costa poco. Supponiamo che il 40% delle richieste sia servito dalla cache (hit rate 0,4).
Con la cache al 40% solo il 60% del traffico passa dal collegamento: 0,6 × 1,5 = 0,9 Mbps, per un utilizzo di 0,9 / 1,54 = 0,58 e code trascurabili. Il ritardo medio è 0,6 × 2,01 s + 0,4 × pochi ms ≈ 1,2 secondi: meno che con il collegamento da 154 Mbps, e a una frazione del costo.
Il GET condizionale e la cache del browser
Una copia in cache può essere vecchia: nel frattempo l'oggetto sul server potrebbe essere cambiato. Il GET condizionale risolve il problema senza spreco: la cache (o il browser) non si fa rimandare l'oggetto se la sua copia è aggiornata.
- Il client indica nella richiesta la data della sua copia:
If-Modified-Since: <data>. - Se l'oggetto non è cambiato da quella data, il server risponde
304 Not Modifiedsenza l'oggetto: niente ritardo di trasmissione e niente banda sprecata. - Se è cambiato, risponde
200 OKcon la nuova versione.
Oggi si usa spesso anche l'ETag, un'impronta della versione: il client rimanda quella che conosce con If-None-Match. Rivedi lo scenario «GET condizionale» nello strumento qui sopra.
Anche ogni browser ha la sua cache. Con l'intestazione Cache-Control il server decide come deve comportarsi:
| Valore | Significato | Adatto a |
|---|---|---|
max-age=31536000 | usa la copia per un anno senza chiedere niente | file che non cambiano mai, come logo.3f9a.png con una versione nel nome |
no-cache | tieni la copia, ma prima di usarla chiedi sempre al server (GET condizionale) | pagine HTML che cambiano spesso |
no-store | non salvare nulla | dati riservati, come l'estratto conto |
private / public | solo il browser dell'utente, o anche le cache condivise | pagine personali / contenuti pubblici |
«Ho cambiato il CSS ma non vedo nulla». È quasi sempre la cache del browser che usa ancora la vecchia copia. Ricarica forzando il download con Ctrl + Shift + R (su Mac Cmd + Shift + R), oppure disattiva la cache nella scheda Rete degli strumenti per sviluppatori.
HTTP/2 e HTTP/3
Il blocco in testa alla coda
HTTP/1.1 permette di inviare più richieste GET di fila sulla stessa connessione TCP (pipelining), ma il server risponde nell'ordine in cui le ha ricevute (FCFS, first come, first served). Se la prima richiesta è per un oggetto grande, un video, gli oggetti piccoli che vengono dopo devono aspettare che finisca: è il blocco in testa alla coda, head-of-line blocking (HOL). E se si perde un segmento TCP, la sua ritrasmissione ferma tutto quello che viene dopo.
HTTP/2
HTTP/2 (RFC 7540, 2015; oggi RFC 9113) ha l'obiettivo di ridurre il ritardo delle pagine con molti oggetti. Metodi, codici di stato e quasi tutte le intestazioni restano gli stessi di HTTP/1.1: cambia il modo in cui i messaggi viaggiano.
- I messaggi non sono più testo, ma binari, e le intestazioni vengono compresse.
- Gli oggetti vengono divisi in frame, e i frame di oggetti diversi si alternano sulla stessa connessione: si attenua il blocco HOL.
- L'ordine di trasmissione segue una priorità indicata dal client, non più l'ordine di arrivo.
- Il server può inviare oggetti non ancora richiesti (server push). In pratica questa funzione si è rivelata poco utile e i browser principali l'hanno abbandonata.
HTTP/3 e QUIC
HTTP/2 viaggia comunque su una sola connessione TCP. Se si perde un pacchetto, TCP ferma tutto finché non l'ha ritrasmesso, e quindi si bloccano tutti gli oggetti: i browser sono di nuovo spinti ad aprire più connessioni in parallelo. In più, TCP da solo non offre sicurezza.
HTTP/3 (RFC 9114, 2022) risolve il problema cambiando trasporto: gira su QUIC (Quick UDP Internet Connections), un protocollo costruito sopra UDP, nato in Google e usato da Chrome e YouTube. QUIC reimplementa affidabilità e controllo della congestione in stile TCP, ma separatamente per ogni oggetto, e integra la cifratura.
Il vantaggio si vede subito all'apertura della connessione. Con TCP e TLS servono due strette di mano in sequenza: prima quella di TCP (affidabilità), poi quella di TLS (autenticazione e cifratura). QUIC stabilisce tutto insieme in un solo RTT. E quando ti ricolleghi a un server già visitato, può usare un «biglietto di sessione» conservato dalla volta prima e mandare dati subito, con 0 RTT di attesa.
Il DNS
Dai nomi agli indirizzi
Le persone hanno molti identificativi: nome, codice fiscale, numero di passaporto. Anche gli host di Internet ne hanno due: l'indirizzo IP a 32 bit, usato per indirizzare i datagrammi, e un nome come cs.umass.edu, usato dalle persone. Come si passa dall'uno all'altro?
Con il DNS (Domain Name System), che è due cose insieme:
- un database distribuito, organizzato in una gerarchia di moltissimi name server;
- un protocollo del livello di applicazione con cui host e name server comunicano per risolvere i nomi, cioè tradurli in indirizzi.
È una funzione vitale per Internet, eppure è realizzata come applicazione ai bordi della rete, non nei router: un esempio della filosofia di Internet, che tiene la complessità ai bordi. Il DNS usa di solito UDP sulla porta 53.
Il DNS offre diversi servizi:
- traduzione da nome a indirizzo IP;
- alias: un host può avere un nome «canonico» complicato e nomi alias più semplici;
www.ibm.com, per esempio, è in realtàservereast.backup2.ibm.com; - alias dei server di posta:
mario@unipi.itfunziona anche se il server di posta si chiama in tutt'altro modo; - distribuzione del carico: i grandi siti hanno molti server replicati, e allo stesso nome corrispondono molti indirizzi IP, restituiti a rotazione.
Un DNS centralizzato sarebbe più semplice, ma non scalerebbe:
- sarebbe un punto di guasto unico: se si ferma, si ferma Internet;
- il volume di traffico sarebbe ingestibile: i soli server DNS di Comcast rispondono a 600 miliardi di richieste al giorno, quelli di Akamai a 2.200 miliardi;
- sarebbe lontano dalla maggior parte degli utenti;
- la manutenzione di un unico enorme database sarebbe impossibile.
Il DNS è invece un database enorme (circa un miliardo di record, ciascuno semplice) che gestisce migliaia di miliardi di richieste al giorno, con molte più letture che scritture. Le prestazioni contano: quasi ogni operazione su Internet passa dal DNS, e ogni millisecondo pesa. È decentralizzato sia organizzativamente (milioni di organizzazioni gestiscono i propri record) sia fisicamente, e deve essere «a prova di proiettile» per affidabilità e sicurezza.
La gerarchia
server radiceIl contatto di ultima istanza per chi non sa risolvere un nome. Esistono 13 server radice logici (da a.root-servers.net a m.root-servers.net), replicati complessivamente in più di mille copie sparse nel mondo. La zona radice è gestita dall'ICANN; DNSSEC aggiunge autenticazione e integrità dei messaggi.
server TLDResponsabili dei domini di primo livello: .com, .org, .net, .edu, .aero, .museum e tutti quelli nazionali, come .it, .uk, .fr, .cn, .jp. .com e .net sono gestiti da Verisign, .edu da Educause, .it dal Registro di Pisa.
server autoritativiI server DNS di un'organizzazione, che danno le risposte ufficiali per i nomi dei suoi host. Li gestisce l'organizzazione stessa o il suo fornitore di servizi.
server localeIl server DNS del tuo ISP, università o rete di casa. Non fa parte della gerarchia: riceve le richieste degli host e le risolve per loro, usando la sua cache o interrogando la gerarchia.
Risoluzione e cache
Un host di engineering.nyu.edu vuole l'indirizzo IP di gaia.cs.umass.edu. Ci sono due modi di procedere:
- interrogazione iterativa: il server contattato risponde con il nome del prossimo server da interrogare, «non lo so, ma chiedi a lui». È il DNS locale a fare tutto il giro;
- interrogazione ricorsiva: il server contattato si fa carico dell'intera risoluzione e ne restituisce il risultato. Il peso ricade tutto sui server più in alto.
Nella pratica la richiesta dell'host al DNS locale è ricorsiva («trovamelo tu»), mentre il DNS locale procede in modo iterativo con radice, TLD e autoritativi.
Appena un name server qualsiasi impara una corrispondenza nome-indirizzo, la tiene in cache e la usa subito per rispondere alle richieste successive. Questo migliora molto i tempi di risposta: gli indirizzi dei server TLD, per esempio, stanno quasi sempre in cache nei server locali, e la radice viene interrogata di rado.
Ogni voce in cache scade dopo un certo tempo, il TTL (time to live). Il rovescio della medaglia è che le voci in cache possono essere superate: se un host cambia indirizzo IP, il cambiamento potrebbe non essere noto in tutta Internet finché tutti i TTL non sono scaduti. Il DNS è un servizio best effort. È il motivo per cui, quando si sposta un sito su un nuovo server, si dice di «aspettare la propagazione del DNS».
Record e domini
Il DNS memorizza record di risorsa (RR) nel formato (nome, valore, tipo, ttl). Il significato di nome e valore dipende dal tipo:
| Tipo | Nome | Valore | Esempio |
|---|---|---|---|
A | nome di un host | il suo indirizzo IPv4 | (gaia.cs.umass.edu, 128.119.245.12, A) |
AAAA | nome di un host | il suo indirizzo IPv6 | (www.esempio.it, 2001:db8::1, AAAA) |
NS | un dominio | il nome del server autoritativo del dominio | (umass.edu, dns.umass.edu, NS) |
CNAME | un alias | il nome canonico, quello vero | (www.ibm.com, servereast.backup2.ibm.com, CNAME) |
MX | un dominio | il server di posta che riceve per quel dominio | (unipi.it, mx.unipi.it, MX) |
TXT | un nome | testo libero, usato per verifiche e antispam | (esempio.it, "v=spf1 …", TXT) |
Una nuova start-up, «Network Utopia», vuole il suo sito. Ecco i passi:
- registra il nome
networkutopia.compresso un registrar, un'azienda autorizzata alla vendita dei domini, fornendo nomi e indirizzi IP dei suoi server DNS autoritativi (primario e secondario); - il registrar inserisce nel server TLD di
.comdue record:(networkutopia.com, dns1.networkutopia.com, NS)(dns1.networkutopia.com, 212.212.212.1, A) - la start-up configura il suo server autoritativo, all'indirizzo 212.212.212.1, con il record
Adiwww.networkutopia.com(ed eventualmente un recordMXper la posta).
Provalo. Dal terminale: nslookup www.unipi.it (funziona su tutti i sistemi) oppure dig www.unipi.it su macOS e Linux, che mostra anche il TTL. Con dig unipi.it MX vedi i server di posta.
Il viaggio completo di una richiesta
Ora hai tutti i pezzi. Ecco cosa succede, in ordine, quando scrivi https://www.unipi.it/ e premi Invio:
- URL: il browser scompone l'indirizzo: schema
https, hostwww.unipi.it, porta 443 predefinita, percorso/. - DNS: se l'indirizzo non è già in cache, chiede al DNS locale l'IP di
www.unipi.it, che lo trova interrogando la gerarchia. - TCP: apre una connessione con il server, all'indirizzo trovato e alla porta 443. È un RTT.
- TLS: negozia la cifratura e verifica il certificato del server; ora compare il lucchetto. Con HTTP/3 i passi 3 e 4 si fondono in uno solo.
- HTTP: invia la richiesta
GET / HTTP/1.1conHost: www.unipi.ite i suoi cookie. - Server: il web server trova il file, o lo genera con un programma, e risponde
200 OKcon il documento HTML. - Altri oggetti: il browser legge l'HTML, trova fogli di stile, immagini, script e font, e li richiede, spesso in parallelo e sulla stessa connessione.
- Rendering: costruisce dall'HTML l'albero degli elementi (il DOM), applica le regole CSS, calcola le posizioni di ogni elemento (layout) e disegna i pixel sullo schermo (paint).
Dietro ogni passo ci sono i livelli visti all'inizio del modulo: messaggi HTTP dentro segmenti TCP, dentro datagrammi IP, dentro frame Wi-Fi, instradati di router in router. Nel prossimo modulo si entra nel file HTML stesso: il linguaggio HTML.