Serveur Apache HTTP Version 2.2

Le code gérant les serveurs virtuels a été réécrit à partir de 
    zéro dans Apache 1.3. Ce document vise à expliquer 
    dans le détail comment Apache procède lors du choix de l'utilisation 
    d'un serveur virtuel en fonction d'une requête reçue. L'apparition 
    de la directive  NameVirtualHost 
    a rendu beaucoup plus facile et plus sûre la configuration des 
    serveurs virtuels par rapport aux versions précédant la 1.3.
Si vous voulez juste que ça marche sans en comprendre le fonctionnement, voici quelques exemples.
Un serveur  principal (main_server) contient toutes 
    les définitions qui apparaissent en dehors des sections 
    <VirtualHost>. Les serveurs virtuels, aussi 
    appelés vhosts (pour virtual hosts), sont définis par les 
    sections <VirtualHost>.
Les directives
    Listen,
    ServerName,
    ServerPath,
    et ServerAlias
    peuvent être placées n'importe où dans le cadre de définition d'un
    serveur. Cependant, chaque fois que l'une d'elles est lue, elle écrase 
    ses instances précédentes (dans le contexte du même serveur).
La valeur par défaut du champ Listen pour le serveur 
    principal est de 80. Le serveur principal n'a pas de valeur par 
    défaut pour ServerPath ni pour ServerAlias. 
    La valeur par défaut de ServerName est déduite à partir 
    de l'adresses IP du serveur.
La directive Listen associée au serveur principal a deux utilités. La première détermine le port réseau sur lequel Apache va écouter. La deuxième spécifie le port qui sera utilisé dans les URIs absolus lors des redirections.
À la différence du serveur principal, les ports des serveurs virtuels n'affectent pas les ports sur lesquels Apache se met à l'écoute.
Chaque adresse incluse dans une directive VirtualHost 
    peut disposer d'un port optionnel. Si le port n'est pas précisé, il 
    prend par défaut la dernière valeur de Listen lue dans 
    la configuration du serveur principal. Le port particulier 
    * représente un joker qui correspond à tous les ports. 
    L'ensemble des adresses (y compris les résultats multiples 
    A issus des requêtes DNS) est appelé jeu 
    d'adresses du serveur virtuel.
À moins qu'une directive 
    NameVirtualHost ne soit utilisée 
    pour une adresse IP spécifique, le premier serveur virtuel avec 
    cette adresse est considéré comme un serveur virtuel par-IP. 
    L'adresse IP peut également prendre la valeur joker *.
Dans les cas où l'on souhaite utiliser un serveur virtuel 
    par nom, la directive NameVirtualHost doit 
    apparaître avec l'adresse IP choisie. En d'autres termes, vous devez 
    spécifier dans votre fichier de configuration l'adresse IP des noms 
    de domaine (CNAME) de vos serveurs virtuels par nom au moyen de 
    la directive NameVirtualHost.
On peut utiliser plusieurs directives NameVirtualHost 
    pour un groupe de directives VirtualHost, mais seule 
    une directive NameVirtualHost doit être utilisée pour 
    chaque couple IP:port donné.
L'ordre d'apparition des directives NameVirtualHost 
    et VirtualHost est sans importance, ce qui fait que 
    les deux exemples suivants ont des effets identiques (seul l'ordre 
    des directives VirtualHost pour un jeu 
    d'adresses est important, voir ci-dessous) :
  | 
  | 
(Il est conseillé d'adopter le choix de gauche pour faciliter la lisibilité des fichiers de configuration.)
Après la lecture de la directive VirtualHost, le 
    serveur virtuel se voit attribuer une valeur Listen 
    par défaut qui est la valeur du port associé au premier nom spécifié 
    dans sa directive VirtualHost.
La liste complète des noms d'une directive VirtualHost 
    est gérée exactement comme des ServerAlias (mais ne 
    sont pas écrasés par d'autres ServerAlias) si tous 
    les noms sont résolus dans ce jeu d'adresse. À noter que les états 
    Listen de ce serveur virtuel sont sans incidence sur 
    les ports attibués au jeu d'adresses.
Pendant la phase d'initialisation, une liste de chaque adresse 
    IP est générée et introduite dans une table de 'hash'. Si une 
    adresse IP est utilisée dans une directive NameVirtualHost, 
    cette liste contient les noms des serveurs virtuels pour cette 
    adresse. Si aucun serveur virtuel n'est défini pour cette adresse, 
    la directive NameVirtualHost est ignorée et un message 
    est envoyé au journal d'erreurs. Quand un serveur virtuel par IP 
    est utilisé, la table de 'hash' reste vide.
La fonction de 'hash' étant rapide, le temps d'exécution d'un 'hash' sur une adresse IP lors d'une requête est minimale et quasiment imperceptible. De plus, la table est optimisée pour les adresses IP dont le dernier octet est le seul à changer.
Pour chaque serveur virtuel, diverses valeurs sont initialisées par défaut. En particulier :
ServerAdmin,
      ResourceConfig,
      AccessConfig,
      Timeout,
      KeepAliveTimeout,
      KeepAlive,
      MaxKeepAliveRequests,
      ou SendBufferSize,
      alors la valeur de chacun de ces paramètres est héritée de celle du
      serveur principal. (C'est à dire, héritée de la valeur finale après
      lecture de la configuration du serveur principal.)L'essentiel des valeurs de configuration des serveurs virtuels provient de valeurs par défaut issues du serveur principal. Mais la position dans le fichier de configuration des directives du serveur principal n'a pas d'importance -- l'ensemble de la configuration du serveur principal est lu avant que ces valeurs par défaut soient appliquées aux serveur virtuels. Ainsi, même si la définition d'une valeur apparaît après celle d'un serveur virtuel, cette valeur peut affecter la definition du serveur virtuel.
Dans le cas où le serveur principal n'a pas de ServerName 
    à ce stade, le nom de la machine sur laquelle tourne le programme 
    httpd est utilisé à sa place. Nous appellerons 
    jeu d'adresses du serveur principal, les adresses IP 
    renvoyées par une résolution DNS sur le ServerName 
    du serveur principal.
Pour tous les champs ServerName non définis, dans 
    le cas d'une configuration en serveur virtuel par nom, la valeur 
    adoptée par défaut est la première adresse donnée dans la section 
    VirtualHost qui définit le serveur virtuel.
Si un serveur virtuel contient la valeur magique 
    _default_, il fonctionne sur le même ServerName 
    que le serveur principal.
À la réception d'une requête, le serveur procède comme suit pour déterminer quel serveur virtuel utiliser :
Après que le client se soit connecté, l'adresse IP à laquelle le client s'est connecté est recherchée dans la table de hash IP interne.
Si la résolution de l'adresse IP n'aboutit pas (adresse IP non 
    trouvée), la requête est servie par le serveur virtuel 
    _default_ s'il est défini pour le port correspondant 
    à la requête. Sinon, elle est servie par le serveur principal.
Si l'adresse IP n'est pas trouvée dans la table de hash, la 
    recherche du numéro de port peut aussi se terminer par une 
    correspondance à un NameVirtualHost * qui est géré 
    ensuite comme les autres serveur virtuels par noms.
Si une liste est bien trouvée dans la table pour l'adresse IP recherchée, l'étape suivante est de déterminer s'il s'agit d'un serveur virtuel par nom ou par IP.
Si l'entrée trouvée dispose d'une liste de noms vide, c'est qu'il s'agit d'un serveur virtuel par IP, et aucun autre choix n'est plus à faire ; la requête est servie par ce serveur virtuel.
Si l'entrée trouvée correspond à un serveur virtuel par nom, 
    la liste de noms contient au moins une structure de serveurs 
    virtuels. Les serveurs virtuels se présentent dans cette liste 
    dans le même ordre que la lecture des directives VirtualHost 
    dans le fichier de configuration.
Le premier serveur virtuel de cette liste (donc, le premier 
    serveur virtuel attribué à une adresse IP donnée dans le fichier 
    de configuration) se voit attribuer la plus grande priorité, ce 
    qui signifie que c'est lui qui traite les requêtes présentant un 
    nom de serveur invalide ou ne présentant pas de champ 
    Host: dans l'en-tête.
Si un champ Host: est transmis dans l'en-tête de 
    la requête, son occurrence est recherchée dans la liste et le 
    premier serveur virtuel qui présente un ServerName 
    ou un ServerAlias correspondant est choisi pour 
    servir la requête. Il est possible que le champ Host: 
    contienne un numéro de port, mais Apache utilise toujours le 
    port sur lequel il a effectivement reçu la requête.
Dans le cas où le client a envoyé une requête en HTTP/1.0 sans 
    un champ d'en-tête Host:, il est impossible de 
    déterminer le serveur auquel le client veut se connecter ; l'URI 
    de la requête est recherché dans tous les ServerPath 
    existants. Le premier chemin trouvé est utilisé et la requête est 
    servie par le serveur virtuel correspondant.
Si aucun serveur virtuel n'est trouvé, la requête est servie par le premier serveur virtuel qui écoute sur le port demandé et qui est sur la liste associée à l'adresse IP vers laquelle la requête a été envoyée (comme déjà précisé ci-avant).
La recherche par adresse IP décrite ci-avant n'est faite qu'une fois pour chaque session TCP/IP, alors que la recherche par nom est réalisée pour chaque requête au cours d'une connexion persistante (KeepAlive). En d'autres termes, il est possible pour un client de faire des requêtes sur différents serveurs virtuels par nom, au cours d'une unique connexion persistante.
Au cas où l'URI de la requête est absolu, et que son nom de serveur et son port correspondent au serveur principal (ou l'un des serveurs virtuels configurés), et qu'ils correspondent à l'adresse et au port de la requête, alors l'URI est amputé de son préfixe protocole/nom de serveur/port et traité par le serveur correspondant (principal ou virtuel). Si cette correspondance n'existe pas, l'URI reste inchangé et la requête est considérée comme une requête d'un serveur mandataire (proxy).
NameVirtualHost.ServerAlias et 
      ServerPath ne sont jamais réalisées pour les 
      serveurs virtuels par IP._default_, les 
      serveurs virtuels par nom et par IP, et la directive 
      NameVirtualHost est sans incidence sur le 
      fonctionnement. Seul l'ordre des serveurs virtuels par nom 
      pour une adresse donnée a une importance. Le serveur virtuel 
      par nom qui est présent en premier dans la configuration se 
      voit attribué la priorité la plus haute pour les requêtes 
      arrivant sur son jeu d'adresses IP.Host: n'est jamais utilisé 
      pour les tests de correspondances. Apache ne prend en compte 
      que le numéro de port sur lequel le client a envoyé la requête.ServerPath existe, et se 
      trouve être préfixe d'une autre directive ServerPath 
      qui apparaît plus loin dans la configuration, la première 
      sera toujours utilisée et la deuxième jamais. (Ceci ne se 
      produit que dans le cas où aucun champ Host: 
      n'a été présenté par le client pour distinguer les deux.)_default_ ne sert la requête 
      que si aucun autre serveur virtuel travaillant sur l'adresse 
      IP et le port demandés n'est trouvé. La requête n'est 
      traitée que si le numéro de port qui a reçu la requête est 
      associé au serveur virtuel _default_ (qui par 
      défaut, correspond à Listen). Un port joker peut 
      être spécifié (comme dans _default_:*) 
      pour récupérer les requêtes sur tous les ports ouverts. Ceci 
      est également applicable aux serveurs virtuels 
      NameVirtualHost *._default_). En d'autres termes, le serveur 
      principal n'est utile que pour les combinaisons adresse/port 
      non spécifiées (sauf quand un serveur virtuel _default_ 
      correspond au port)._default_, ni le 
      serveur principal ne sont utilisés pour traiter une requête 
      avec un champ d'en-tête Host: manquant ou vide 
      lorsque l'adresse (et le port) de connexion correspondent à 
      des serveurs virtuels par nom, par exemple, dans une directive 
      NameVirtualHost.VirtualHost, car cela oblige le serveur a s'appuyer 
      sur le DNS au moment du démarrage. De plus, vous vous exposez 
      à des problèmes de sécurité si vous n'avez pas la maîtrise du 
      DNS pour la totalité de vos domaines. Voir la documentation 
      disponible ici, ainsi que 
      les deux points précisés ci-après.ServerName devrait toujours 
      être indiqué pour chaque serveur virtuel. Sans cela, une 
      résolution DNS est nécessaire pour chaque serveur virtuel.En plus des points évoqués sur la page des problèmes liés au DNS, voici quelques points intéressants :
VirtualHost. 
      (Ceci améliore grandement la lisibilité de la configuration 
      -- la manière dont la configuration est interprétée après la 
      lecture des fichiers ne met pas en évidence le fait que les 
      définitions positionnées avant et surtout après les serveurs 
      virtuels peuvent impacter le fonctionnement des serveurs virtuels.)NameVirtualHost 
      et VirtualHost dans la configuration pour une 
      meilleure lisibilité.ServerPaths qui sont préfixes 
      d'autres ServerPaths. Si cela ne peut être évité, 
      veillez à ce que le serveur virtuel contenant le préfixe le plus 
      long (donc le plus précis) apparaisse dans le fichier de 
      configuration avant le plus court. (par exemple, 
      "ServerPath /abc" est à spécifier après  "ServerPath /abc/def").