Skip to content

Latest commit

 

History

History
208 lines (158 loc) · 9.91 KB

12. HTTP.md

File metadata and controls

208 lines (158 loc) · 9.91 KB

Intro

URI - Unified Resource Identifier - rappresenta in modo univoco qualsiasi risorsa del pianeta.

#Nota la rappresentazione della risorsa ritornata può variare

Comunicazione client-server

Il protocollo HTTP implementa un paradigma di programmazione request-response

#Attenzione prima di una richiesta HTTP viene aperta una comunicazione TCP attraverso il 3way handshake (SYN, SYN-ACK, ACK).

Questo pattern di comunicazione identifica che il server può rispondere solo a richieste fatte dal client. Il ruolo di ogni partecipante nella comunicazione rimane sempre lo stesso (client, server).

Messaggi

Sintassi

L'HTTP viene originariamente definito come protocollo testuale.

Un protocollo testuale non può essere definito in maniera rigorosa; il cuore del protocollo sta nel fatto che l'informazione è fruibile da utenti umani. Un protocollo binario ha necessariamente bisogno di utilizzare una codifica; si rende necessario un software intermedio che esegua codifica e decodifica dei byte.

Definizione (per HTTP testuale):

  • i messaggi sono composti da intestazione e payload
  • l'intestazione è organizzata per linee (terminate da CRLF - 0x0a 0x0d):
    • la prima indica l'operazione (verbo HTTP)
    • successivamente si trovano potenzialmente più righe chiamate header
    • una linea vuota per separare intestazione da payload (ovvero CRLF - Carrier Return Line Feed)
------------------
verb
------------------
key1: val1
key2: val2
...
keyN: valN
------------------

------------------
payload
------------------

Richiesta

GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3
Host: www.example.com
Accept-Language: en, mi

Request line:

  • GET richiesta
  • /hello.txt URI della risorsa in formato UNIX-like
  • HTTP/1.1 versione di HTTP, dato che ne esistono varie. Identificata da major.minor

#Attenzione hello.txt può essere una qualsiasi risorsa, non necessariamente un file testuale.

Header (espresso con la convenzione chiave-valore):

  • User-Agent: curl/7.16.3 libcurl/7.16.3 il client specifica quale software sta usando.
  • Accept-Language: en, mi richiede la risorsa nella lingua specificata
  • Host: www.example.com serve a gestire il multiplexing a livello HTTP. Questo campo deve essere (quasi) sempre incluso; tipicamente i server web rifiutano richieste senza questa chiave.

A cosa serve? sequenzialmente, quando cerchiamo di contattare www.unimore.it:

  1. DNS request to solver
  2. Solver to local NS
  3. DNS response
  4. Three way handshake (TCP 80 di default)
    1. (c->s) SYN
    2. (s->c) SYN-ACK
    3. (c->s) ACK + HTTP GET request
  5. HTTP response

Se lo stesso amministratore gestisce, ad esempio, pippo.com e unimore.it, riceveremo le richieste per i due origin server. Il campo Host permette una logica di multiplazione.

#Attenzione dall'HTTP in poi è differente inviare richieste a unimore.it o a 155.185.2.122

Risposta

Il messaggio di risposta ha una struttura analoga alla richiesta. Divisione in header e payload:

  • response line: HTTP-version SEP status-code SEP reason-phrase CRLF
    • La versione di HTTP contenuta nella riposta è idealmente minore o uguale a quella della richiesta. Eg. richiesta in 1.1 e risposta in 1.0. Tipicamente stessa major version e minor version minore o uguale
    • Lo status code è un intero da 3 cifre decimali che descrive il risultato dell'operazione (eg. 200)
    • La reason phrase fornisce una descrizione human-readable della riposta (eg. OK)

Classi di status code

Ogni prefisso identifica una macro-categoria di stati. Perché? le best-practice del web prevedono che un origin server gestisca almeno ogni categoria di status code.

Gerarchia dei codici di errori:

  • 1xx - richiesta ricevuta, il processing continua perché il risultato non è ancora pronto. Spesso un task asincrono.
  • 2xx - la richiesta è stata ricevuta, interpretata e accettata. Tutto a buon fine.
    • 200 OK
    • 201 Crated: utilizzato da verbi di scrittura
    • 202 Accepted
  • 3xx - sono necessarie da parte del client ulteriori azioni al fine di completare la richiesta
    • 300 Multiple Choices
    • 301 Moved Permanently (tipicamente legato al redirect)
    • 302 Found
    • 303 See Other
    • 304 Not Modified (la risorsa è già in cache, il server lo deduce dal timestamp contenuto nell'header della richiesta)
  • 4xx - la richiesta ha una sintassi errata, non può essere soddisfatta (errore lato client)
    • 400 Bad Request (generico errore sintattico da parte del client)
    • 401 Unauthorized (legata al controllo degli accessi)
    • 402 Payment Required (legata al controllo degli accessi)
    • 403 Forbidden (legata al controllo degli accessi)
    • 404 Not Found (errore di richiesta lato client)
  • 5xx - il server non è riuscito a soddisfare la richiesta, che è apparentemente valida (errore lato server). Si tende a offuscare l'errore avvenuto sul server.

URI sintax

Superset della sintassi HTTP. Un URI generico è definito così:

scheme ":" hier-part ["?" query] ["#" fragment]
hier-part = "//" authority-part path-abempty
authority-part = [userinfo "@"] hostname [":" port]
path-abempty = (/|[/segment]*)

Eg: http://[userinfo@]<hostname>[:<port>]/<path>

#Nota abempty = absolute empty

La porta è opzionale. Il valore di default viene dedotto sulla base dello schema (porta standard per quel protocollo). userinfo è utilizzato per logiche di autenticazione, ad esempio in SSH.

#Nota l'hostname è case-insensitive, in quanto è gestito dal DNS. La case sensitivity dipende dal server, dato che non esiste uno standard che lo definisca. Se il webserver è statico dipende dal filesystem. I fs EXT (Linux) sono case sensitive, i fs NTFS (Windows) sono insensitive.

La query è definita con il paradigma chiave=valore, in cui l'elemento separatore è &. I simboli non rappresentabili sono trasportati con il loro valore intero in forma esadecimale. Eg: %20 per lo spazio, %7E per la tilde. Anche =, ? e & devono essere inviati come hex (forma non codificata).

Il path contiene almeno la radice, non può mai essere vuoto.

Il frammento rappresenta una sotto-risorsa della risorsa originale. Ad esempio il capitolo di una pagina di documentazione. Il frammento è introdotto dal cancelletto o hash, in inglese.

Metodi

Verbi standard

GET è il metodo per la lettura di una risorsa. HEAD è simile al GET ma non ritorna il contenuto della risorsa, solamente prima riga e header. Usato tipicamente per sapere se una risorsa esiste. POST è il metodo generalmente usato per creazione e modifica di una risorsa, compreso invio di form. POT permette la sostituzione della risorsa DELETE per l'eliminazione della risorsa PATCH per la modifica della risorsa

CRUD - Create Read Update Delete

Estendibilità

Abbiamo definito il protocollo come estendibile, in quanto nuovi metodi possono essere inventati e implementati dallo sviluppatore. Ad esempio: metodo PLAY di un mediaplayer.

OPTIONS e TRACE

OPTIONS richiede le operazioni permesse sul server TRACE è usato per scopi diagnostici. Esegue un echoing della richiesta

Header

Accept

Il client specifica con quale codifica desidera che la risorsa gli venga ritornata. Mediante l'header Accept l'user agent specifica come la risorsa dovrebbe essere ritornata dal server.

Accept: text/plain; ...

#Approfondisci sono chiamati MIME - Multipurpose Internet Mail Extensions - types

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

text/plain documento di testo senza ulteriori rappresentazioni. Eg. text/html, text/x-c (file il C lang)

Metadati sul payload

Lo standard MIME specifica quali sono i tipi standard inviabili/accettabili su richieste HTTP.

Content-Type definisce il formato o la codifica del contenuto del payload. Comunica come interpretare i dati trasferiti. Eg. application/XXX implica un certo tipo di codifica, come base64 e base32 per la trasmissione di dati binari su formato testuale (come v.1 di HTTP)

HTTP state

HTTP è un protocollo stateless. La connessione viene chiusa alla fine della risposta (1.0) o allo scadere di un timeout (1.1)

I cookie sono il meccanismo che permette di aggiungere lo stato ad HTTP -> lo rende stateful

Come funziona?

  • quando origin restituisce una risposta, può inviare l'header Set-Cookie: ...
  • se lo user application supporta il meccanismo dei cookie, ad ogni richiesta invierà un header contenente il cookie fornito dal server

Si può generalizzare il meccanismo con il nome di token opaco: ovvero, i dati inviati dal server non devono essere interpretati dal client. Il client è memoria al posto del server.

Set-Cookie: SID=1234567;[Attr1=Val1; Attr2...]

Il meccanismo più semplice è quello del SID - Session ID; un tipo di token opaco di tipo reference. Un meccanismo SID + IP rende più sicuro il servizio, ma in un contesto di roaming si perderebbe la correlazione.

Oltre al valore del cookie, sono disponibili altri parametri che ne possono restringere l'uso:

  • Path definisce il sottoalbero a cui il cookie si applica; utile quando lo stesso webserver gestisce più servizi sulla base del path.
  • Domain
  • Secure
  • HttpOnly non trasmettere il cookie in HTTP
  • Expires sessioni di cookie dalla durata limitata

Cancellazione di un cookie: il server manda un Set-Cookie con Expires nel passato o Max-Age minore o uguale a zero.

Autenticazione

In HTTP esiste un meccanismo per l'autenticazione. Non deve essere gestito a livello applicativo. Si identifica dall'interfaccia nativa del browser.

#Prova con i tool di sviluppo

  1. cerchiamo di accedere alla risorsa
  2. riceviamo una risposta 401 unauthorized
  3. il browser mostra il dialog
  4. viene inviata una richiesta con il protocollo della basic authentication
Authorization: Basic ZHNhOmFzZa==

Questa autorizzazione viene gestita completamente lato client. Il clienti invia ad ogni richiesta la password impostata sul dialog.

La lunghezza di una stringa in base64 è multipla di 3. Gli uguali sono padding per l'allineamento.