Una delle caratteristiche del protocollo HTTP è la sua capacità di inviare qualsiasi tipo di informazione, immagini, testo, codice eseguibile e quant'altro.
Apache esegue un vero e proprio attachment a questi pacchetti aggiungendo un header Content-Type che specifica al client a quale media type o MIME type appartiene il file.
File Types
Apache acquisisce informazioni sul MIME-type dal file di configurazione (generale per tutto il sistema) chiamato mime.types oppure dal file settato tramite la direttiva TypesConfig
TypesConfig
conf/mime.types
Ecco un piccolo esempio del contenuto di un simile file:
[root@dido root]# cat /usr/local/apache/conf/mime.types
application/x-shockwave-flash swf
application/x-tar tar
application/x-tcl tcl
application/x-tex tex
application/x-texinfo texinfo texi
application/x-troff-man man
application/x-wais-source src
Oltre che editando questo file è possibile aggiungere nuovi MIME type direttamente nel file di configurazione principale di Apache (httpd.conf) tramite la direttiva AddType ed abbinarla alla direttiva Action per affiancare l'esecuzione di una azione specifica ad ogni tipo di file richiesto.
Questo succede per molti moduli i quali richiedono l'esecuzione di cgi o di comandi esterni ad Apache.
AddType text/mylanguage .myl .mylanguage
Action image/gif /cgi-bin/process-gif.cgi
L'alternativa alla direttiva Addtype è AddHandler che mappa direttamente l'estensione con il MIME type, oppure ForceType che associa tutto il contenuto di una directory ad un MIME type.
AddHandler cgi-script .cgi
<Directory /images/>
ForceType image/gif
</Directory>
File Encoding
Ogni estensione di file è associata al tipo di encoding utilizzato per la sua creazione. Tramite la direttiva AddEncoding è possibile mappare queste corrispondenze.
Come succedeva per i Mime-type, Apache invia un header aggiuntivo, Content-Encoding per comunicare al client quale tipo di encoding è stato utilizzato per un certo file:
AddEncoding x-gzip .gz
AddEncoding x-compress .Z
File Languages
Oltre alle caratteristiche sopra esposte, è possibile associare una lingua ad un certa risorsa. In questo caso l'header contenente l'informazione è Content-Language e la direttiva utilizzata èAddLanguage:
AddLanguage en .en .english
AddLanguage it .it .italy .italian
La lingua di default è settabile tramite la direttiva DefaultLanguage, che permette anche più argomenti, trattati con la priorità scritta:
General configuration:
DefaultLanguage en in
Per-directory configuration
<Directory /italy/>
DefaultLanguage it
</Directory>
Il protocollo HTTP definisce 4 header che il client invia al server per specificare quali risorse hanno priorità rispetto ad altre o semplicemente quelle che vengono rifiutate.
Accept
Header che specifica quali Mime types accetterà il client, e con quale preferenza:
Accept: text/html, image/ *, application/pdf
in questo caso il client accetta tutti i documenti in html e qualsiasi tipo di immagine e di pdf, dando la priorità ai documenti html, poi alle immagini ed infine i documenti in pdf
Accept-Charset
Header che specifica i charset che il client accetta:
Accept-Charset: iso-8859, *
Accept-Encoding
Gli encodings che il client accetta:
Accept-Encoding: bzip2, gzip, zip
Accept-Language
Le lingue accettate dal client (in ordine di preferenza):
Accept-Language: en,fr,de
Tramite la direttiva Multiviews è possibile configurare Apache per fare un'appending automatico della estensione (secondo le entry del file mime.types) ad un file richiesto che non esiste.
Attivazione della direttiva Multiviews
Options +Multiviews
Ammettiamo che sia stata attivata per la directory /pippo/ e che venga fatta una richiesta per il file /pippo/index.html, se il file index.html non esiste, in modo automatico Apache cercherà nella directory tutti i seguenti documenti index.html.* a seconda delle entry in mine.types. Questa soluzione è molto vantaggiosa per quando si ha che fare con siti multilingua.
A seconda del protocollo utilizzato il proxy di Apache agisce in modo diverso al relay di una risorsa che ha dovuto "subire" un Content Negotiation.
HTTP/1.1
Il protocollo in se definisce tramite un set di header, associati alle richieste HTTP, quali risorse possono essere messe in cache ed in quali condizioni.
HTTP/1.0
Per tutti i client che utilizzano il vecchio protocollo, Apache "marca" tutte le risorse negoziate come risorse non cacheabili, tramite l'header no-cache.
Questa configurazione standard può essere facilmente superata tramite un direttiva da specificare a livello di server configuration del proxy server.
Tale direttiva è CacheNegotiateDocs
, non richiede ulteriori argomenti ed ha effetto solo con i client che utilizzano il protocollo HTTP/1.0.
Quando la direttiva Multiviews o le type maps sono attivate bisogna considerare 4 varianti per la selezione di un file:
- MimeType
- Encoding
- Language
- Character set
La procedura è stata creata per risolvere tutte le possibili varianti:
- Vengono estratti i valori dei parametri settati con gli Accept-* header, e per tutti questi valori viene confrontata con le varianti in type maps e la ricerca tramite la direttiva Multiviews.
- Se nessuna delle varianti passa il test, viene generato un errore 406 - NO acceptable representation, il quale produce una pagina html contenente la lista delle possibili varianti, altrimenti viene selezionata la migliore secondo i seguenti step:
- Viene moltiplicato il fattore Accept quality con il fattore source quality per ogni variante. Se dal prodotto di questi fattori risulta più alto tale variante vincerà il content altrimenti verranno selezionate le varianti con il più alto language quality factor.
- Se anche nel caso precedente non vi è nessun risultato dominante rispetto ad altri, verranno selezionate le varianti con un livello più alto di media parameter (Di default i documenti in formato text/html hanno un livello pari a 2 mentre tutti gli altri a 0). Se, anche in questo caso, non viene prodotto un singolo risultato vincente occorre selezionare la variante con la miglior charset media parameter selezionata dell'header Accept-Charset.
- Il passo successivo, nel caso in cui la negoziazione dovesse continuare, è quello di selezionare le varianti con il migliore encoding, tramite i valori settai tramite l'header Accept-Encoding.
- Se anche l'ultimo confronto dovesse fallire viene selezionata la prima variante:
la prima entry del file nel caso di type map,
la prima variante in ordine alfabetico nel caso di Multiviews.
- A questo punto, la richiesta del client è stata soddisfatta. Il server si preoccupa di inviare un header aggiuntivo vary header che indica il criterio di selezione nel content negotiation, questo è molto utile per evitare un ulteriore content negotiation della stessa risorsa.
Il problema della direttiva MultiViews è dato dal fatto che è solo il client a decidere quale priorità dare ad un documento rispetto ad un altro.
Tramite il modulo mod_negotiation che associa la funzionalità di Multiviews e di type maps è possibile configurare lato server queste preferenze.
Per configurare Apache in modo tale che utilizzi le type maps lo si associa ad una estensione.
L'estensione più utilizzata è .var ed è settabile tramite la direttiva AddHandler:
AddHandler type-map .var
Adesso si possono definire le server preferences per ogni documento .var.
Ovviamente tutti i browser non sono configurati per richiedere documenti .var quindi occorre aggiungere un piccolo work-around lato server tramite Rewrite:
RewriteRule ^(.*).html$ $1.var [NS]
Il contenuto del file type map è una serie di records (uno per ogni tipo di file), ecco un piccolo elenco dei vari headers permessi:
URI
La relativa URI del file, rispetto alla locazione della type map:
URI: lang/it/index.html.it
Content-Type
Il content-Type del file:
Content-Type: text/html
Content-Encoding
Content-Encoding del file se ne ha una.
Content-Language
La lingua del file, se ne ha una.
Content-Lenght
Lunghezza del file, se presente Apache utilizzerà il valore settato per eventuali check.
Description
Aggiunge una stringa che descrive la variante del file.
Type maps File example:
URI: index.html.en
Content-Type: text/html
Content-Language: en
Description: "English"
URI: index.html.de
Content-Type: text/html
Content-Language: de
Description: "German"
URI: index.html.it
Content-Type: text/html
Content-Language:it
Description: "Italian"
E' possibile definire i quality parameter per i singoli valori settati tramite gli Accept-* headers sia per specificare le preferenze del client che del server. Questi paramentri vengono inseriti negli header delle risposte HTTP di Apache.
Se il quality parameter viene omesso è come se fosse settato ad 1, il valore minimo è 0, sono ammessi numeri decimali intermedi. La sintassi con cui vengono sctitti nel file di configurazione è la stessa con cui vengono indicati negli header HTTP.
Client Preferences
Accept: text/html, text/plain;q=0.5
Server Preferences
Content-Type text/html;qs=0.5
In tutte le piattaforme Unix, esiste un comando chiamato file che, confrontando i primi byte di un file con dei pattern noti, può dedurre il tipo del file stesso.
Questo è possibile perchè diversi file dello stesso tipo (per esempio immagini GIF) hanno sempre alcuni byte in comune (di solito all'inizio) che li identificano e permettono ai programmi che li utilizzano di riconoscerli e trattarli opportunamente. Molti tipi di file sono associati ad un "magic number" in modo univoco.
Questa funzionalità si può applicare anche in ambito web tramite Apache ed il modulo mod_mime_magic.
Il modulo mod_mime_magic è un supplemento rispetto alle direttive MIME gestite dal modulo mod_mime.
I vantaggi nell'utilizzo del primo modulo derivano dal fatto che non è necessario aggiungere direttive o modificare file di configurazione mime.type oppure semplicemente dal fatto che alcuni file non possono essere distinti dall'estensione.
Queste operazioni costano molto in termini di prestazione e di velocità di risposta del server ed è proprio per questo che la configurazione consigliata è l'utilizzo di entrambi i moduli, dando precedenza al caricamento di mod_mime ed in un secondo tempo, se il primo dovesse fallire nel riconoscere il file type il caricamento del modulo mod_mime_magic.
Il modulo in questione fa parte della configurazione standard di Apache ma a differenza del modulo mod_magic che carica di default il file mime.type, occorre specificare a livello di server configuration il caricamento del proprio file di configurazione, che solitamente risiede nella sottodirectory conf del tree di Apache:
MimeMagicFile conf/magic
Ecco come si presentano le entry del file magic:
[byte offset] [match type] [match criterion] [MIME type] ([encoding])
0 string \000\000\001\263 video/mpeg
-offset
Indica da quale byte, rispetto all'inizio del file, inizia l'analisi
-match type
E' simbolo che identifica il tipo di match da eseguire (es una stringa oppure un set di bit)
-match criterion
Dipende esclusivamente dal match type (es: Se match type è una stringa allora sarà testo oppure può contenere valori espressi in scala ottale)
-MIME type/ encoding
Lo standard mime type (text/html etc..)
E' possibile settare sul server la priorità dei linguaggi, poiché molti browser non inviano l'header Accept-Language, rendendo inutile la funzionalità della direttiva Multiviews.
LanguagePriority en de fr it ...
Apache è molto flessibile nella gestione delle estensioni dei file, poiché si ha la possibilità di aggiungere content-type, encoding e language senza seguire un certo ordine.
Questo perchè Multiviews lavora appendendo una wildcard (*) al file, quindi per la richiesta del file index.html potra' matchare sia con index.html.en, sia index.html.en.gz o index.html.gz.en ma non potrà matchare per esempio con index.en.html.gz
MIME e' l'acronimo di "Multipurpose Internet Mail Extension", originariamente era stato sviluppato per poter includere nei messaggi di posta elettronica oggetti non testuali.
Con l'evoluzione di Internet, si evoluto anche questo standard, divenendo lo standard internazionale per definire i contenuti di oggetto in un range di protocolli, compreso l'HTTP.