# HTTP

## Introduzione

`HTTP` sta per *Hypertext Transfer Protocol* ed è il protocollo incaricato di gestire lo scambio di richieste e risposte http in un'architettura client-server. Questo protocollo è utilizzato per lo scambio di pagine web e altri contenuti multimediali. HTTP è associato alla well-known port *80*, mentre `HTTPS` (la versione sicura di HTTP) utilizza la porta *443*. Ciò significa che il processo sul server relativo a questi servizi è tipicamente legato a queste porte.

In quanto protocollo dell'application layer, HTTP si appoggia al TCP del transport layer per garantire una comunicazione affidabile e robusta. Prima che avvenga lo scambio dei veri e propri messaggi, è necessario stabilire una connessione TCP tra il client e il server.

## Tipologie di connessione HTTP

- **Connessione non persistente:** un metodo tradizionale in cui per ogni richiesta HTTP viene instaurata una sessione TCP separata. Questo approccio, essendo meno efficiente, può comportare un uso eccessivo di risorse, in particolare quando vengono richieste numerose risorse in rapida successione
- **Connessione persistente:** con questo metodo, una volta stabilita la connessione TCP tra il client e il server, tutte le risorse vengono scambiate utilizzando la stessa connessione. Solo al termine dello scambio della totalità delle risorse la connessione viene chiusa. Questo approccio è molto più efficiente, poiché riduce il sovraccarico derivante dall'instaurazione ripetuta di nuove connessioni TCP

## HTTP Request

Una richiesta HTTP è strutturata in quattro macrosezioni:

1. `Riga di richiesta`: contiene il metodo HTTP (ad esempio, GET, POST, PUT, DELETE, ecc.) e la versione di HTTP utilizzata, solitamente la versione 2
2. `Intestazione` o `Header`: ena serie di coppie chiave-valore che forniscono al server ulteriori informazioni, come ad esempio il tipo di contenuto, le informazioni sul client, le preferenze sulla codifica, e altro ancora
3. `Riga vuota`: Separa le intestazioni dal corpo della richiesta
4. `Corpo della richiesta` o `Body` (Opzionale): contiene i dati da inviare al server

![http-request](asset/img/http-request.png)

### Intestazione della Richiesta HTTP

Gli header di una richiesta HTTP vengono utilizzati dal client per fornire al server informazioni utili all'elaborazione della risposta. Alcuni dei principali campi utilizzati:

- `User-Agent`: specifica il tipo di client utilizzato per la richiesta, ad esempio il browser o l'applicazione
- `Accept`: indica quali tipi di contenuti il client è in grado di gestire. Ad esempio, l'header `Accept-Language` comunica le preferenze linguistiche del browser, permettendo al server di restituire contenuti nella lingua preferita
- `Connection`: Determina se la connessione TCP deve rimanere aperta o essere chiusa subito dopo la risposta. Il valore `keep-alive` serve a mantenere attiva la connessione
- `Host`: specifica l'host e la porta di destinazione della richiesta
- `Referrer`: indica il percorso o path da cui è partita la richiesta
- `Cookie`: invio dei cookie associati alla sessione o ad altre informazioni di identificazione, utili per mantenere lo stato della sessione utente e per personalizzare l'esperienza
- `Content-Type`: Specifica il tipo di contenuto che il client sta inviando nel corpo della richiesta, ad esempio `application/json` o `text/html`
- `Content-Length`: indica la dimensione, in byte, del contenuto presente nel corpo della richiesta
- `If-Modified-Since`: questo campo contiene un timestamp che indica l'ultima modifica nota al client. Il server utilizza questo dato per decidere se inviare il contenuto richiesto o restituire un codice 304 (*Not Modified*) se il contenuto non è stato aggiornato successivamente alla data specificata

![header-http](asset/img/header-http.png)

## HTTP Response

Una risposta HTTP è il messaggio che un server invia a un client (come un browser o un'applicazione) dopo aver ricevuto e processato una richiesta HTTP. La struttura di una risposta HTTP è composta da quattro elementi principali:

- `Riga di stato`, la prima riga della risposta che include la *versione del protocollo HTTP*, il *codice di stato* e la frase di stato descrittiva (ad esempio, *OK*)
- `Headers`: le righe successive contengono le intestazioni, organizzate come coppie chiave-valore. Queste intestazioni forniscono informazioni supplementari sulla risposta, quali il tipo di contenuto, la lunghezza del contenuto e altri metadati
- `Riga vuota` che separa le intestazioni dal corpo della risposta.
- `Body`: il corpo del messaggio, che contiene i dati effettivi della risposta

![http-response](asset/img/http-response.png)

### Codici di stato

I codici di stato HTTP sono numeri a tre cifre che il server invia al client per indicare l'esito di una richiesta. Si suddividono in cinque categorie principali, identificate dalla prima cifra:

- `1XX` - *Informativi*: indicano che la richiesta del client è stata ricevuta e il server sta proseguendo con l'elaborazione (es. *100 Continue*)
- `2XX` - *Successo*: la richiesta è stata compresa e accettata correttamente dal server (es. *200 OK*)
- `3XX` - *Redirect*: la richiesta richiede ulteriori azioni per essere completata, solitamente tramite un reindirizzamento a un nuovo URL. (es. *301 Permanently Redirect*)
- `4XX` - *Errori del client*: indicano che la richiesta contiene errori, ad esempio di sintassi o perché la risorsa richiesta non è stata trovata (es. *400 Bad Request*, *404 Not Found*)
- `5XX` - *Errori del server*: il server ha incontrato un errore o una condizione impossibile da gestire che ha impedito la soddisfazione della richiesta (es. *500 Internal Server Error*, *503 Service Unavailable*)

![http-status-code](asset/img/http-status-code.png)

### Intestazione della Risposta HTTP

Le intestazioni di risposta permettono al server di fornire al client (tipicamente un browser) informazioni aggiuntive sul messaggio restituito. Tra le più importanti:

- `Content-Type`: specifica il tipo di contenuto della risposta, ad esempio `text/html`, `application/json`, ecc.
- `Content-Length`: indica la lunghezza del corpo della risposta, espressa in byte
- `Date`: riporta la data e l’ora (*timestamp*) in cui il messaggio è stato generato dal server
- `Server`: indica il software (e talvolta la versione) in uso sul server HTTP
- `Set-Cookie`: invia uno o più cookie al client, che potrà conservarli e ritrasmetterli nelle richieste successive per gestire sessioni, preferenze o tracciamento dell’utente.
- `Cache-Control`: fornisce direttive su come il client (o eventuali proxy intermedi) deve memorizzare nella cache la risposta
- `Expires`: definisce una data/ora oltre la quale la risposta è considerata scaduta e non più valida in cache
- `Last-Modified`: specifica il timestamp dell’ultima modifica della risorsa richiesta
- `ETag`: un identificatore univoco (e solitamente in forma di hash) della versione corrente della risorsa. Consente al client di effettuare richieste condizionali (`If-None-Match`) per verificare se la risorsa è cambiata
- `Location`: utilizzata nei codici di stato *3xx* per indicare al client l’URL di destinazione a cui effettuare il reindirizzamento
- `Allow`: elenca i metodi HTTP che il server supporta per la risorsa richiesta

## Metodi HTTP

I metodi HTTP indicano al server l'azione da eseguire su una risorsa. I principali metodi:

- `GET`: il metodo più comune, serve per richiedere una risorsa presente sul server. Non utilizza il corpo (body) della richiesta; eventuali parametri vengono passati direttamente nell'URL, dopo il carattere `?` e separati tramite il carattere `&`. Ad esempio: `https://miosito.com/?filtro=1&rilasciato=false`
- `POST`: utilizzato per inviare dati al server, ad esempio i dati di un modulo di login. In questo caso, le informazioni vengono trasmesse tramite il corpo della richiesta
- `HEAD`: serve per richiedere informazioni (metadata) su una risorsa, senza scaricarne l'intero contenuto. Questo metodo è utile per verificare ad esempio l'esistenza della risorsa
- `PUT`: utilizzato per creare o aggiornare una risorsa sul server. Questo metodo, tuttavia, è spesso disabilitato per motivi di sicurezza
- `TRACE`: impiegato a fini diagnostici e di debugging, aiutando a identificare eventuali problemi lungo il percorso della richiesta
- `DELETE`: consente di eliminare una risorsa sul server. Anche questo metodo, per ragioni di sicurezza, è spesso disabilitato di default
- `OPTIONS`: utilizzato per verificare quali metodi HTTP sono supportati dal server, consentendo così al client di conoscere le possibili azioni disponibili

## Cookie e sessioni

Il protocollo HTTP è progettato per il trasferimento di pagine web attraverso richieste e risposte. Tuttavia, il protocollo HTTP è intrinsecamente `stateless`, ovvero privo di memoria. Ciò significa che non può memorizzare le preferenze o lo stato di un utente tra una richiesta e l'altra.

Per ovviare a questa limitazione, sono stati introdotti i cookie e le sessioni, che rendono HTTP `stateful`, un meccanismo con memoria che può tenere traccia dell'utente.

I `cookie` sono piccoli file di testo che il server invia al browser dell'utente, che li memorizza. Quando l'utente effettua una nuova richiesta, il browser invia nuovamente i cookie al server, permettendogli di riconoscere l'utente e mantenere le sue preferenze.

Le caratteristiche principali dei cookie sono:

- *Persistenza*: possono essere di sessione (temporanei, eliminati alla chiusura del browser) o persistenti (con una data di scadenza e memorizzati sul disco)
- *Sicurezza*: possono essere marcati come `secure`, obbligando lo scambio solo tramite HTTPS, e `HttpOnly`, impedendo di accedere al valore del cookie tramite JavaScript. Questo è un ulteriore strumento di protezione contro attacchi di furto d'identità (i cookie permettono di bypassare tutti i meccanismi di autenticazione)
- *Scope*: definiscono il percorso (path) e il dominio (domain) per cui il cookie è valido

Hanno una dimensione limitata a 4 KB e possono essere bloccati dal browser o dai suoi plugin per motivi di privacy.

Le `sessioni`, invece, sono gestite lato server e identificano il client attraverso un ID di sessione. Questo approccio offre un ulteriore livello di sicurezza, poiché i dati sensibili non vengono memorizzati nel cookie, ma rimangono sul server.

Le sessioni sono generalmente utilizzate in combinazione con i cookie: il cookie contiene solo l'ID di sessione, mentre le informazioni associate all'utente sono archiviate sul server.

## URI, URL e URN

Un `URI` (*Uniform Resource Identifier*) è un meccanismo per identificare in modo univoco una risorsa generica. Esistono due specializzazioni principali:

- `URL` (*Uniform Resource Locator*): è comunemente utilizzato nel web e specifica il percorso dove la risorsa può essere raggiunta. Segue il formato: `protocollo://{hostname o nome dominio/ip}[:porta]/percorso/?parametro1=valore1&parametro2=valore2...`
- `URN` (*Uniform Resource Name*): rappresenta il contesto o namespace in cui è inserita la risorsa, senza indicarne il percorso di accesso. Un URN consente, ad esempio, di classificare un libro in base al suo genere, indipendentemente dalla sua ubicazione specifica
