Smanettando con Mojolicious, mi sono ritrovato a guardare meglio il protocollo http (rfc 2616), che in effetti ho sempre usato ma approfondito poco.
Un po’ di info estese si possono trovare su wikipedia, ma in sostanza HTTP è un protocollo che si basa su richieste di uno user agent (client) e risposte di un web server (server).
Generalmente ad una richiesta del client segue una risposta del server che può fornire risorse di qualunque genere, anche se generalmente server file HTML – interpretati poi dal client; un messaggio di risposta contiene informazioni sullo stato (attraverso un codice numerico), vari header, e eventualmente un contenuto.
Le risorse HTTP sono identificate da URI (Uniform Resource Identifiers) o, più precisamente, URL (Uniform Resource Locators) che ne permettono la chiamata.
La principale differenza fra la versione del protocollo 1.0 e la 1.1 è che la specifica più recente permette di riutilizzare la medesima connessione più volte – mentre la versione più antica richiedeva una connessione separata per ogni transazione richiesta-risposta.
Richiesta
Un messaggio di richiesta può presentarsi come segue:
GET /get/20120105_002516.jpg HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Length: 0
Host: localhost:19987
La richiesta presenta un metodo, un URI e un protocollo, alcuni header aggiuntivi, e la linea “Host:” che determina a chi stiamo chiedendo la risorsa (obbligatorio nella v. 1.1).
Risposta
La risposta del server alla nostra richiesta è la parte interessante. In cima c’è lo status della risposta, seguito da una serie di header che possono fornire informazioni aggiuntive di vario genere; infine, dopo una riga vuota, segue il corpo.
X-Powered-By: Mojolicious (Perl)
Connection: keep-alive
Date: Thu, 05 Jan 2012 22:57:04 GMT
Server: Mojolicious (Perl)
Content-Length: 22880
Un body se presente mandato via HTTP request o response è in un formato codificato definito dagli header.
Quando un corpo (entity-body indica l’insieme di oggetti serviti come corpo – compresa ad esempio una codifica di sicurezza) è incluso in un messaggio, il tipo del body è determinato via Content-Type e Content-Encoding.
Il Content-Type specifica il tipo di media e l’Encoding può essere usato per, ad esempio, compressioni applicate ai dati; non vi è alcun Content-Encoding di default.
Qualunque messaggio HTTP/1.1 contenga un body dovrebbe includere un Content-Type: in caso di mancanza, il client può provare a capire cosa gli viene mandato; se l’ispezione non ha successo, il ricevente dovrebbe trattare il file come “application/octet-stream”.
Anche il Content-Length è molto importante perchè fornisce informazioni sul numero di byte passati.
Domanda malefica: se un header viene specificato anche in un file html con , quale ha precedenza, il valore specificato durante l’http handshake o quello contenuto nel file stesso ?
(riproviamo…) un file html con meta <http-equiv=”" content=”" />
Quindi prima di tutto vengono letti gli header HTTP e il client a questo punto SA la risposta (e il tipo), poi viene parsato il body che viene renderizzato nella risorsa HTML.
A questo punto il meta-tag html mi pare più che altro informativo (anche se può influenzare il rendering del client, forse).
Faccio due prove.
Ok, dopo varie prove ho visto che ha la precendenza l’header http.
A mio avviso gli header nei meta tag sono informativi (per chi legge il contenuto senza poter conoscere la risposta http) – in pratica dovrebbero coincidere con quelli passati dal server.
Leggendo qui e là, ho trovato articoli che propongono la lettura da parte del server del body da servire, e quindi il parsing degli eventuali http-equiv e la sostituzione da parte del server al momento della generazione della response.
Pare che un server che lo fa sia tal WN… http://hopf.math.northwestern.edu/
In pratica, ognuno fa quel c@zzo che vuole, e’ il client che arbitrariamente decidera’ che fare; alcuni browser rispettano il meta tag piu’ dell’header, e spesso i meta sono comunque sbagliati (specialmente quelli relativi all’encoding: se ti passo un file che il server dice essere ascii, il meta dice di essere utf-8, e il file stesso in realta’ e’ cp1252, come fai a renderlo correttamente?).
Il che’ significa che gli unici header di cui ci si puo’ sempre fidare sono quelli relativi al protocollo stesso (e.g. codice, referral, etc), non al contenuto.
Beh, in realtà come ti dicevo, la precedenza ce l’ha l’header del server.
Il protocollo dice così.
Il rendering dipende sempre dalle scelte del client, ma si deve basare su delle info corrette – non dedotte da lui. Quelle info sono quelle degli header http.
Eh ma il fatto e’ che i server non controllano quello che mandano, per cui le info *relative al contenuto* semplicemente non sono affidabili. Altro esempio: il mimetype. Molti server (*cough*IIS*cough*) deducono il mimetype dall’estensione, che non e’ sempre necessariamente corretta. And on and on