Serveur Apache HTTP Version 2.0

Apache suit les spécifications HTTP/1.1 en ce qui concerne les négociations de contenus. Il est ainsi possible d'utiliser les informations fournies par le navigateur (préférences de langues, jeu de caractères, encodage et types de médias). Apache essaye aussi d'optimiser les cas des navigateurs envoyant des informations incomplètes.
C'est le module mod_negotiation qui fournit
    la négociation de contenus ; ce module est inclus dans Apache 
    par défaut.
Différentes représentations peuvent être utilisées pour communiquer une ressource. Par exemple, plusieurs langues peuvent être disponibles, ou plusieurs types de médias, voire parfois une combinaison de ces possibilités. Une méthode pour gérer cela est de donner le choix au visiteur, en lui proposant un index général, qui lui permet par exemple de choisir sa langue. Cependant, il est souvent possible de faire ce choix de manière automatique car les navigateurs peuvent préciser avec leurs requêtes, la représentation qu'ils préfèrent recevoir. Par exemple, un navigateur pourrait spécifier qu'il préfère recevoir les informations en français si elles sont disponibles, ou en anglais dans le cas contraire. Ce type d'information est communiqué par les navigateurs, dans les en-têtes de chaque requête. Un navigateur ne demandant que des documents en français enverrait
Accept-Language: fr
Notez que cette préférence ne sera gérée par le serveur que s'il existe un choix de langues du côté du serveur.
Voici un exemple plus complet, où le navigateur est configuré pour accepter le français et l'anglais, mais avec une préférence pour le français, et pour accepter divers types de médias, en préférant le HTML au texte brut, et en préférant le GIF ou le JPEG aux autres types de médias (sans pour autant refuser ces derniers, le cas échéant) :
  Accept-Language: fr; q=1.0, en; q=0.5
  Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
Apache supporte les négociations de contenus 'gérés par
    le serveur', telles que spécifiées dans HTTP/1.1. Les en-têtes
    Accept, Accept-Language, 
    Accept-Charset et Accept-Encoding 
    sont gérés. Apache supporte également les négociations de 
    contenus 'transparentes', telles que définies dans les RFC
    2295 et 2296. En revanche les fonctions de 'feature 
    negotiation' définies dans ces RFCs ne sont pas supportées.
On appelle ressource une entité conceptuelle identifiée par un URI (RFC 2396). Le travail d'un serveur HTTP, tel Apache, est de donner un accès à des représentations des ressources à sa disposition, chaque représentation étant envoyée sous la forme d'une séquence d'octets définie selon un type de média, un jeu de caractères, un encodage, etc. À tout moment, chaque ressource est associée à zéro, une ou plusieurs représentations. Si plusieurs représentations sont disponibles pour une ressource, on dit que cette dernière est négociable et chacune de ses représentations possibles est appelée une variante. Les différentes possibilités de choisir les variantes d'une ressource négociable sont appelées dimensions de la négociation.
Pour qu'Apache puisse procéder à la négociation d'une ressource, il faut qu'il dispose d'informations à propos de chacune des variantes. Deux méthodes sont possibles :
*.var) qui précise explicitement les fichiers
      définissant les variantes, ouUne table de types est un document qui est associé avec le 
    gestionnaire type-map (ou, dans les plus anciennes 
    versions d'Apache, le type mime application/x-type-map).
    Notez que pour implémenter cette méthode, un 'handler' doit être
    défini dans la configuration pour associer une extension de fichier à 
    type-map ; ce qui est généralement obtenu au moyen de
AddHandler type-map .var
dans le fichier de configuration du serveur.
Les fichiers de table de types portent généralement le nom de la 
    ressource qu'ils décrivent, et contiennent une entrée correspondant
    à chaque variante possible ; ces entrées sont constituées de lignes
    au format d'en-têtes HTTP. Les entrées de deux variantes distinctes
    sont à séparer par des lignes vides. Il n'est pas permis d'utiliser
    des lignes vides au sein d'une entrée. Il est courant de placer en 
    début de fichier une entrée pour l'entité combinée 
    dans son ensemble (bien que cela ne soit pas nécessaire, et ignoré
    par Apache). Un exemple de fichier de table est donné en exemple
    ci-après. Le nom de ce fichier serait foo.var, puisque
    le fichier décrit une ressource appelée foo.
  URI: foo
  URI: foo.en.html
  Content-type: text/html
  Content-language: en
  URI: foo.fr.de.html
  Content-type: text/html;charset=iso-8859-2
  Content-language: fr, de
Notez que les fichiers de table de types sont toujours utilisés en priorité par Apache par rapport à l'extension du nom du fichier, et ce même si l'option Multiviews est activée. Des variantes présentant des qualités inégales peuvent être indiquées au moyen du paramètre de type de média : "qs", comme dans le cas de cette image (disponible en JPEG, GIF ou ASCII-art) :
  URI: foo
  URI: foo.jpeg
  Content-type: image/jpeg; qs=0.8
  URI: foo.gif
  Content-type: image/gif; qs=0.5
  URI: foo.txt
  Content-type: text/plain; qs=0.01
Les valeurs de qs acceptables sont comprises entre 0.000 et 1.000. Notez qu'une variante avec un qs de 0.000 ne sera jamais choisie. La valeur de qs par défaut est de 1.0. Le paramètre qs sert à indiquer la qualité de la variante, par rapport aux autres variantes disponibles, et ce indépendamment des possibilités du navigateur. Par exemple, un fichier JPEG est généralement de meilleure qualité qu'un fichier ASCII, si les 2 documents sont destinés à représenter une photographie. Bien sûr, si la ressource originale est elle-même un fichier ASCII, la représentation ASCII sera considéré comme de meilleure qualité que la représentation JPEG. La valeur de qs dépend donc de la nature de la ressource que l'on souhaite représenter.
La liste complète des en-têtes utilisables est disponible dans la documentation de mod_negotation.
L'option MultiViews est à spécifier par répertoire,
    ce qui signifie qu'elle peut être utilisée au moyen d'une directive
    Options dans une section 
    <Directory>, 
    <Location> ou 
    <Files> 
    du fichier httpd.conf, ou dans les fichiers 
    .htaccess (à condition que l'option AllowOverride soit paramétrée pour cela).
    Notez que Options All n'active pas l'option
    MultiViews ; cette dernière doit être positionnée
    explicitement.
Voici comment fonctionne MultiViews : supposons qu'un
    serveur reçoive une requête pour /some/dir/foo, que l'option
    MultiViews soit activée pour /some/dir, 
    et que le fichier /some/dir/foo n'existe 
    pas ; alors le serveur cherche les fichiers nommés foo.* 
    dans le répertoire /some/dir, et construit une table de types à 
    partir de ces noms de fichiers. Dans la table, chaque fichier se 
    voit assigner les types de médias et les encodages de contenu 
    tels qu'ils seraient envoyés si le client les demandait par leur
    nom propre. Apache choisit alors la meilleure représentation à 
    envoyer au client, en fonction de ses préférences.
L'option MultiViews sert aussi lors du choix d'un
    index, lorsque la directive DirectoryIndex est précisée. 
    Par exemple, si la configuration contient
DirectoryIndex index
le serveur devra choisir entre les fichiers index.html et
    index.html3, dans le cas où ces deux fichiers existent. Si
    aucun de ces fichiers n'existe, mais qu'un fichier index.cgi
    est présent, ce dernier sera exécuté par le serveur.
Si à la lecture du répertoire, un fichier est trouvé 
    dont l'extension n'est pas reconnue par mod_mime 
    comme précisant son jeu de caractères, sa langue, son type de 
    contenu (Content-Type) ou son encodage, alors tout dépendra de la 
    directive MultiViewsMatch.
    Cette directive précise en effet quels gestionnaires, filtres, et
    autres types d'extensions peuvent contribuer à la négociation
    MultiViews.
Après qu'Apache ait défini la liste de variantes possibles pour une ressource, que ce soit via un fichier de tables de types ou à partir des noms de fichiers contenus dans le répertoire, deux méthodes peuvent être invoquées pour choisir la 'meilleure' variante qui sera envoyée, pour autant qu'il en existe au moins une. Il n'est pas nécessaire de connaître ce fonctionnement pour utiliser les négociations de contenu avec Apache ; cependant pour le lecteur intéressé la suite de ce document s'attache à décrire ce fonctionnement.
Il existe deux méthodes de négociations :
| Dimension | Notes | 
|---|---|
| Type de Média | Le navigateur présente ses préférences au moyen du 
        champ Acceptde l'en-tête. À chaque élément peut être 
        associé un facteur de qualité. De la même manière, la description 
        de la variante peut présenter un facteur de qualité (le 
        paramètre "qs"). | 
| Langues | Le navigateur présente ses préférences au moyen du champ Accept-Languagede l'en-tête. À chaque élément 
        peut être associé un facteur de qualité. Les différentes 
        variantes peuvent également être associées ou non à une 
        ou plusieurs langues. | 
| Encodage | Le navigateur présente ses préférences au moyen du champ Accept-Encodingde l'en-tête. À chaque élément 
        peut être associé un facteur de qualité. | 
| Jeu de caractères | Le navigateur présente ses préférences au moyen du champ Accept-Charsetde l'en-tête. À chaque élément 
        peut être associé un facteur de qualité. Les différentes 
        variantes peuvent se voir associer un jeu de caractères 
        comme type de média. | 
Apache peut utiliser l'algorithme présenté ci-après pour choisir la 'meilleure' variante, si elle existe, à renvoyer au navigateur. Cet algorithme n'est pas configurable. Il fonctionne de cette manière :
Accept par le facteur qualité de la source du 
          type de média de cette variante, et choisir les variantes 
          avec le plus grand résultat.Accept-Language (s'il existe), 
          soit à l'ordre des langues de la directive 
          LanguagePriority (si elle existe).Accept-Charset. 
          Le jeu de caractères ISO-8859-1 est toujours acceptable, à 
          moins qu'il n'ait été explicitement refusé. Les variantes 
          avec un type de média test/* et qui ne sont 
          pas explicitement associées à un jeu de caractère donné 
          sont supposées encodées en ISO-8859-1.Vary de la réponse HTTP 
      est utilisé pour indiquer les dimensions de la négociation 
      (les navigateurs et les serveurs mandataires sont capables de 
      prendre en compte cette information quand il gardent une 
      ressource en cache). Fin des opérations.Vary est également renseigné pour présenter les 
      dimensions de la négociation.Il arrive qu'Apache modifie les facteurs de qualité par rapport 
    à la valeur qu'ils devraient avoir en suivant strictement 
    l'algorithme décrit plus haut. Ceci permet d'obtenir de meilleurs 
    résultats pour gérer les navigateurs qui n'envoient pas toutes 
    les informations ou envoient des informations erronées. Ainsi, 
    certains navigateurs, parmi les plus répandus du marché, envoient 
    des en-têtes Accept qui entraîneraient l'envoi de la 
    mauvaise variante dans de nombreux cas. Si le navigateur envoie 
    des informations correctes, Apache ne trichera pas sur les facteurs 
    de qualité.
L'en-tête de requête Accept: indique les préférences 
    des types de médias. Elle peut comporter des 'jokers' tels que 
    "image/*" ou "*/*", où * signifie "n'importe quoi". Ainsi, une 
    requête présentant :
Accept: image/*, */*
signifierait que tout type commençant par "image/" est acceptable, comme serait acceptable tout autre type. Certains navigateurs envoient sans arrêt des jokers en plus des types qu'ils peuvent effectivement gérer. Par exemple :
  Accept: text/html, text/plain, image/gif, image/jpeg, */*
Le but de ces informations est d'indiquer que les types explicitement cités sont les préférés mais que le navigateur accepte également d'autres représentations. En utilisant les facteurs de qualité, voici ce que devrait envoyer le navigateur :
  Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
Les types explicitement cités ne présentent pas de facteur de qualité, ils reçoivent donc la valeur par défaut de 1.0 (la plus haute valeur possible). Les jokers sont affectés d'une préférence très basse de 0.01, si bien que les autres types ne seront utilisés que si aucune des variantes ne correspond à un des types explicitement préférés.
Si le champ d'en-tête Accept: ne 
    contient aucun facteur de qualité, Apache modifie 
    le facteur de qualité de "*/*" (s'il est présent) en 0.01 
    afin d'émuler le comportement souhaité. Apache positionne 
    également le facteur de qualité des jokers qui se présentent 
    sous la forme "type/*" en 0.02 (afin que ces derniers soient 
    préférés à "*/*"). Si un seul ou plusieurs types de média de 
    l'en-tête Accept: présente un facteur de qualité, 
    ces modifications ne sont pas effectuées, 
    afin que les requêtes des navigateurs qui envoient des 
    informations correctes fonctionnent comme prévu.
À partir d'Apache 2.0, certaines exceptions ont été ajoutées à l'algorithme de négociation afin de retomber élégamment sur nos pattes dans les cas où la négociation sur la langue n'aboutit pas.
Si un client demande une page du serveur, sans que ce dernier 
    ne puisse déterminer une page correspondant au champ 
    Accept-language envoyé par le navigateur, le serveur 
    doit renvoyer une réponse parmi "Pas de Variante Acceptable" 
    et "Choix Multiples" au client. Afin d'éviter ces messages 
    d'erreur, il est possible de configurer Apache pour qu'il ignore 
    le champ Accept-language dans ces cas et qu'il 
    fournisse au client un document qui ne correspond pas 
    explicitement à sa requête. La directive 
    ForceLanguagePriority 
    peut être utilisée pour passer outre à ces deux messages d'erreur 
    et modifier la réponse du serveur au moyen de la directive 
    LanguagePriority.
Le serveur va également essayer de modifier la sous-classe 
    de langue si aucune correspondance n'est trouvée. Par exemple, 
    dans le cas où un client demande des documents avec le langage 
    en-GB pour "British English", le protocole HTTP/1.1 
    n'autorise pas le serveur à répondre par un document qui serait 
    marqué par en. (Notez que présenter 
    en-GB dans l'en-tête Accept-language 
    est loin d'être pertinent, il semble très peu probable que le 
    lecteur comprenne l'anglais "British" et ne comprenne pas 
    l'anglais "tout court". Il se trouve malheureusement que 
    beaucoup de navigateurs présentent ce comportement.) Bref, 
    si aucune autre langue ne correspond et que le serveur 
    s'apprêterait normalement à envoyer une réponse d'erreur 
    "No Acceptable Variants", ou à utiliser la méthode 
    LanguagePriority 
    présentée ci-avant, le serveur va ignorer la sous-classe de 
    langue GB et considérer que la requête 
    en-GB correspond bien au document en. 
    Implicitement, Apache ajoute la langue parente (en) 
    à la liste des langues considérées comme acceptables par le 
    navigateur, avec un facteur de qualité très faible. Notez 
    cependant que si le client demande "en-GB; qs=0.9, fr; qs=0.8", 
    et que le serveur dispose de documents marqués comme "en" et 
    "fr", alors le document en français sera renvoyé par le serveur. 
    Ce comportement est nécessaire, afin de garder la compatibilité 
    avec HTTP/1.1 et fonctionner avec les navigateurs correctement 
    configurés.
Pour supporter les techniques avancées de détection de
    préférence de langues de l'utilisateur (telles que les 
    Cookies, ou les chemins d'URL spéciaux), Apache reconnaît 
    depuis la version 2.0.47 la variable 
    d'environnement prefer-language. Si cette 
    variable existe, et qu'elle précise une langue valide, 
    mod_negociation cherchera une variante qui 
    y corresponde. S'il n'en trouve pas, le processus de 
    négociation normal se déroulera.
      SetEnvIf Cookie "language=en" prefer-language=en
      SetEnvIf Cookie "language=fr" prefer-language=fr
    
Apache complète le protocole de négociation de contenu (RFC 2295) 
comme décrit ici. Un nouvel élément {encoding ..} est 
utilisé dans la liste des variantes pour nommer celles qui ne sont 
disponibles que sous un encodage spécifique. L'implémentation de 
l'algorithme RVSA/1.0 (RFC 2296) est étendue afin d'intégrer les 
variantes encodées dans la liste, et de les proposer comme 
candidates quand leur encodage est acceptable au vu de l'en-tête 
Accept-Encoding. L'implémentation RVSA/1.0 ne tronque 
pas les facteurs de qualité à 5 décimales avant de choisir la 
meilleure des variantes.
Dans le cas où la négociation de langues est utilisée, il est possible de choisir diverses conventions de nommage, car les fichiers peuvent présenter plus d'une extension, et l'ordre des extensions n'est normalement pas significatif (voir la documentation mod_mime pour plus de détails).
Habituellement, un fichier a une extension pour son type MIME 
    (par exemple, html), parfois une extension pour son 
    encodage (par exemple, gz), et bien sûr une extension 
    de langue (par exemple, en) pour distinguer les 
    diverses variantes.
Exemples :
Voici d'autres exemples de noms de fichiers ainsi que des liens hypertextes valides et invalides :
| Nom de Fichier | Lien valide | Lien invalide | 
|---|---|---|
| foo.html.en | foo foo.html | - | 
| foo.en.html | foo | foo.html | 
| foo.html.en.gz | foo foo.html | foo.gz foo.html.gz | 
| foo.en.html.gz | foo | foo.html foo.html.gz foo.gz | 
| foo.gz.html.en | foo foo.gz foo.gz.html | foo.html | 
| foo.html.gz.en | foo foo.html foo.html.gz | foo.gz | 
Le tableau ci-dessus montre qu'il est toujours possible de 
    spécifier le lien sans aucune extension dans un lien hypertexte. 
    (par exemple, foo). L'avantage en est qu'il est 
    ainsi possible de ne pas montrer le type d'un document, et de 
    le modifier ultérieurement, par exemple le passer de html 
    à shtml ou cgi sans avoir besoin de 
    modifier aucun lien.
Pour continuer à utiliser les types MIME dans les liens 
    (par exemple, foo.html), l'extension correspondant 
    à la langue (ainsi que l'extension d'encodage, si elle existe) 
    doit être du coté droit de l'extension du type MIME (par exemple, 
    foo.html.en).
Quand un cache garde en mémoire une représentation, il l'associe à l'URL de la requête. Quand la même URL vient à être redemandée, le cache peut utiliser la représentation gardée en mémoire, plutôt que de refaire une requête au serveur. Cependant, si la ressource est négociable coté serveur, le résultat pourrait en être que la réponse à la première requête mise en cache serait renvoyée de façon erronée. Pour prévenir ce problème, Apache marque toutes les réponses issues d'une négociation comme "non-cachables" par les clients HTTP/1.0. Apache supporte les spécifications du protocole HTTP/1.1 en ce qui concerne la mise en cache des réponses négociées.
Les requêtes venant d'un client conforme au protocole HTTP/1.0 
    (qu'il s'agisse d'un navigateur ou d'un serveur cache) peuvent 
    être rendues "cachables" si la directive CacheNegotiatedDocs est 
    utilisée. Cette directive peut être spécifiée aussi bien dans 
    la configuration principale du serveur que dans un serveur 
    virtuel, et ne nécessite pas d'argument. Elle n'a aucun impact 
    sur les requêtes des clients fonctionnant en HTTP/1.1.
Pour plus d'informations au sujet de la négociation de contenu, voir Language Negotiation Notes de Alan J. Flavell. Notez que ce document ne sera peut-être pas mis à jour en fonction des changements intervenus dans Apache 2.0.