<?xml version='1.0' encoding='ISO-8859-1' ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
<!-- English Revision: 151408:833879 (outdated) -->
<!-- French translation by Vincent Deffontaines, review by alain B -->

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<manualpage metafile="details.xml.meta">
<parentdocument href="./">Serveurs virtuels</parentdocument>
   <title>Détails sur le fonctionnement des serveurs virtuels</title>

<summary>

    <p>Le code gérant les serveurs virtuels a été réécrit à partir de 
    zéro dans <strong>Apache 1.3</strong>. 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  <directive module="core">NameVirtualHost</directive> 
    a rendu beaucoup plus facile et plus sûre la configuration des 
    serveurs virtuels par rapport aux versions précédant la 1.3.</p>

    <p>Si vous voulez juste <cite>que ça marche</cite> sans en 
    comprendre le fonctionnement, voici <a href="examples.html">quelques 
    exemples</a>.</p>

</summary>

<section id="configparsing"><title>Interprétation des fichiers 
de configuration</title>

    <p>Un <em>serveur  principal (main_server)</em> contient toutes 
    les définitions qui apparaissent en dehors des sections 
    <code>&lt;VirtualHost&gt;</code>. Les serveurs virtuels, aussi 
    appelés <em>vhosts</em> (pour virtual hosts), sont définis par les 
    sections <directive type="section" module="core">VirtualHost</directive>.</p>

    <p>Les directives
    <directive module="mpm_common">Listen</directive>,
    <directive module="core">ServerName</directive>,
    <directive module="core">ServerPath</directive>,
    et <directive module="core">ServerAlias</directive>
    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).</p>

    <p>La valeur par défaut du champ <code>Listen</code> pour le serveur 
    principal est de 80. Le serveur principal n'a pas de valeur par 
    défaut pour <code>ServerPath</code> ni pour <code>ServerAlias</code>. 
    La valeur par défaut de <code>ServerName</code> est déduite à partir 
    de l'adresses IP du serveur.</p>

    <p>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.</p>

    <p>À la différence du serveur principal, les ports des serveurs 
    virtuels <em>n</em>'affectent <em>pas</em> les ports sur lesquels 
    Apache se met à l'écoute.</p>

    <p>Chaque adresse incluse dans une directive <code>VirtualHost</code> 
    peut disposer d'un port optionnel. Si le port n'est pas précisé, il 
    prend par défaut la dernière valeur de <code>Listen</code> lue dans 
    la configuration du serveur principal. Le port particulier 
    <code>*</code> représente un joker qui correspond à tous les ports. 
    L'ensemble des adresses (y compris les résultats multiples 
    <code>A</code> issus des requêtes DNS) est appelé <em>jeu 
    d'adresses</em> du serveur virtuel.</p>

    <p>À moins qu'une directive 
    <directive module="core">NameVirtualHost</directive> ne soit utilisée 
    pour une adresse IP spécifique, le premier serveur virtuel avec 
    cette adresse est considéré comme un <em>serveur virtuel par-IP</em>. 
    L'adresse IP peut également prendre la valeur joker <code>*</code>.</p>

    <p>Dans les cas où l'on souhaite utiliser un <em>serveur virtuel 
    par nom</em>, la directive <code>NameVirtualHost</code> <em>doit</em> 
    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 <code>NameVirtualHost</code>.</p>

    <p>On peut utiliser plusieurs directives <code>NameVirtualHost</code> 
    pour un groupe de directives <code>VirtualHost</code>, mais seule 
    une directive <code>NameVirtualHost</code> doit être utilisée pour 
    chaque couple IP:port donné.</p>

    <p>L'ordre d'apparition des directives <code>NameVirtualHost</code> 
    et <code>VirtualHost</code> est sans importance, ce qui fait que 
    les deux exemples suivants ont des effets identiques (seul l'ordre 
    des directives <code>VirtualHost</code> pour <em>un</em> jeu 
    d'adresses est important, voir ci-dessous)&nbsp;:</p>

<table><tr>
<td><example>
  NameVirtualHost 111.22.33.44<br />
  &lt;VirtualHost 111.22.33.44&gt;<br />
  # serveur A<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  &lt;VirtualHost 111.22.33.44&gt;<br />
  # serveur B<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  <br />
  NameVirtualHost 111.22.33.55<br />
  &lt;VirtualHost 111.22.33.55&gt;<br />
  # serveur C<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  &lt;VirtualHost 111.22.33.55&gt;<br />
  # serveur D<br />
  ...<br />
  &lt;/VirtualHost&gt;
</example></td>
<td><example>
  &lt;VirtualHost 111.22.33.44&gt;<br />
  # serveur A<br />
  &lt;/VirtualHost&gt;<br />
  &lt;VirtualHost 111.22.33.55&gt;<br />
  # serveur C<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  &lt;VirtualHost 111.22.33.44&gt;<br />
  # serveur B<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  &lt;VirtualHost 111.22.33.55&gt;<br />
  # serveur D<br />
  ...<br />
  &lt;/VirtualHost&gt;<br />
  <br />
  NameVirtualHost 111.22.33.44<br />
  NameVirtualHost 111.22.33.55<br />
  <br />
</example></td>
</tr></table>


    <p>(Il est conseillé d'adopter le choix de gauche pour faciliter 
    la lisibilité des fichiers de configuration.)</p>

    <p>Après la lecture de la directive <code>VirtualHost</code>, le 
    serveur virtuel se voit attribuer une valeur <code>Listen</code> 
    par défaut qui est la valeur du port associé au premier nom spécifié 
    dans sa directive <code>VirtualHost</code>.</p>

    <p>La liste complète des noms d'une directive <code>VirtualHost</code> 
    est gérée exactement comme des <code>ServerAlias</code> (mais ne 
    sont pas écrasés par d'autres <code>ServerAlias</code>) si tous 
    les noms sont résolus dans ce jeu d'adresse. À noter que les états 
    <code>Listen</code> de ce serveur virtuel sont sans incidence sur 
    les ports attibués au jeu d'adresses.</p>

    <p>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 <code>NameVirtualHost</code>, 
    cette liste contient les noms des serveurs virtuels pour cette 
    adresse. Si aucun serveur virtuel n'est défini pour cette adresse, 
    la directive <code>NameVirtualHost</code> 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.</p>

    <p>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.</p>

    <p>Pour chaque serveur virtuel, diverses valeurs sont initialisées 
    par défaut. En particulier&nbsp;:</p>

    <ol>
      <li>Dans le cas où un serveur virtuel ne contient pas de directives 
      <directive module="core">ServerAdmin</directive>,
      <directive module="core">ResourceConfig</directive>,
      <directive module="core">AccessConfig</directive>,
      <directive module="core">Timeout</directive>,
      <directive module="core">KeepAliveTimeout</directive>,
      <directive module="core">KeepAlive</directive>,
      <directive module="core">MaxKeepAliveRequests</directive>,
      ou <directive module="core">SendBufferSize</directive>,
      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.)</li>

      <li>Les permissions par défaut sur les répertoires de chaque 
      serveur virtuel sont assemblées avec celles du serveur principal. 
      Elles concernent également toutes les informations de configuration 
      par répertoire pour tous les modules.</li>

      <li>Les configurations par serveur pour chaque module sont assemblées 
      à partir de celles du serveur principal.</li>
    </ol>

    <p>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.</p>

    <p>Dans le cas où le serveur principal n'a pas de <code>ServerName</code> 
    à ce stade, le nom de la machine sur laquelle tourne le programme 
    <program>httpd</program> est utilisé à sa place. Nous appellerons 
    <em>jeu d'adresses du serveur principal</em>, les adresses IP 
    renvoyées par une résolution DNS sur le <code>ServerName</code> 
    du serveur principal.</p>

    <p>Pour tous les champs <code>ServerName</code> 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 
    <code>VirtualHost</code> qui définit le serveur virtuel.</p>

    <p>Si un serveur virtuel contient la valeur magique 
    <code>_default_</code>, il fonctionne sur le même <code>ServerName</code> 
    que le serveur principal.</p>

</section>

<section id="hostmatching"><title>Choix du serveur virtuel</title>

    <p>À la réception d'une requête, le serveur procède comme suit pour
    déterminer quel serveur virtuel utiliser&nbsp;:</p>

    <section id="hashtable"><title>Vérification dans la table de hash</title>

    <p>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.</p>

    <p>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 
    <code>_default_</code> s'il est défini pour le port correspondant 
    à la requête. Sinon, elle est servie par le serveur principal.</p>

    <p>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 <code>NameVirtualHost *</code> qui est géré 
    ensuite comme les autres serveur virtuels par noms.</p>
    
    <p>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.</p>

    </section>

    <section id="ipbased"><title>Serveur virtuel par IP</title>

    <p>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&nbsp;; la requête est servie par ce serveur virtuel.</p>

    </section>

    <section id="namebased"><title>Serveur virtuel par nom</title>

    <p>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 <code>VirtualHost</code> 
    dans le fichier de configuration.</p>

    <p>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 
    <code>Host:</code> dans l'en-tête.</p>

    <p>Si un champ <code>Host:</code> 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 <code>ServerName</code> 
    ou un <code>ServerAlias</code> correspondant est choisi pour 
    servir la requête. Il est possible que le champ <code>Host:</code> 
    contienne un numéro de port, mais Apache utilise toujours le 
    port sur lequel il a effectivement reçu la requête.</p>

    <p>Dans le cas où le client a envoyé une requête en HTTP/1.0 sans 
    un champ d'en-tête <code>Host:</code>, il est impossible de 
    déterminer le serveur auquel le client veut se connecter&nbsp;; l'URI 
    de la requête est recherché dans tous les <code>ServerPath</code> 
    existants. Le premier chemin trouvé est utilisé et la requête est 
    servie par le serveur virtuel correspondant.</p>

    <p>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).</p>

    </section>

    <section id="persistent"><title>Connexions persistantes</title>

    <p>La recherche par adresse IP décrite ci-avant n'est faite 
    qu'<em>une fois</em> pour chaque session TCP/IP, alors que la 
    recherche par nom est réalisée pour <em>chaque</em> 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.</p>

    </section>

    <section id="absoluteURI"><title>URI absolu</title>

    <p>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), <em>et</em> 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).</p>
</section>

<section id="observations"><title>Observations</title>

    <ul>
      <li>Les serveurs virtuels par nom et par IP n'interfèrent 
      jamais entre eux. Les serveurs virtuels par IP ne sont joignables 
      qu'au travers de leur(s) adresse(s) IP propre(s), en aucun 
      cas par aucune autre adresse. Les serveurs virtuels par nom 
      ne sont accessibles que par leur(s) adresse(s) IP qui ne peuvent 
      être définies qu'au moyen de la directive 
      <code>NameVirtualHost</code>.</li>

      <li>Les vérifications sur <code>ServerAlias</code> et 
      <code>ServerPath</code> ne sont jamais réalisées pour les 
      serveurs virtuels par IP.</li>

      <li>L'ordre dans lequel sont agencés dans le fichier de 
      configuration le serveur virtuel <code>_default_</code>, les 
      serveurs virtuels par nom et par IP, et la directive 
      <code>NameVirtualHost</code> 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.</li>

      <li>Pour des raisons de sécurité, le numéro de port présenté 
      dans le champ d'en-tête <code>Host:</code> 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.</li>

      <li>Si une directive <code>ServerPath</code> existe, et se 
      trouve être préfixe d'une autre directive <code>ServerPath</code> 
      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 <code>Host:</code> 
      n'a été présenté par le client pour distinguer les deux.)</li>

      <li>Dans le cas où deux serveurs virtuels par IP ont une 
      adresse en commun, le serveur virtuel qui apparaît en premier 
      dans la configuration est toujours choisi. Ce genre de chose 
      peut arriver par inadvertance. Le serveur envoie une alerte 
      dans le journal d'erreurs si ce cas se présente.</li>

      <li>Le serveur virtuel <code>_default_</code> ne sert la requête 
      que si aucun autre serveur virtuel travaillant sur l'adresse 
      IP <em>et</em> 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 <code>_default_</code> (qui par 
      défaut, correspond à <code>Listen</code>). Un port joker peut 
      être spécifié (<em>comme dans</em> <code>_default_:*</code>) 
      pour récupérer les requêtes sur tous les ports ouverts. Ceci 
      est également applicable aux serveurs virtuels 
      <code>NameVirtualHost *</code>.</li>

      <li>Le serveur principal ne sert à servir les requêtes que 
      lorsque l'adresse IP et le port demandés par le client ne 
      correspondent à aucun serveur virtuel (y compris un serveur 
      virtuel <code>_default_</code>). 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 <code>_default_</code> 
      correspond au port).</li>

      <li>Ni les serveurs virtuels <code>_default_</code>, ni le 
      serveur principal ne sont utilisés pour traiter une requête 
      avec un champ d'en-tête <code>Host:</code> manquant ou vide 
      lorsque l'adresse (et le port) de connexion correspondent à 
      des serveurs virtuels par nom, par exemple, dans une directive 
      <code>NameVirtualHost</code>.</li>

      <li>Il ne faut jamais employer de noms DNS dans des directives 
      <code>VirtualHost</code>, 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 
      <a href="../dns-caveats.html">disponible ici</a>, ainsi que 
      les deux points précisés ci-après.</li>

      <li>Un nom de serveur <code>ServerName</code> devrait toujours 
      être indiqué pour chaque serveur virtuel. Sans cela, une 
      résolution DNS est nécessaire pour chaque serveur virtuel.</li>
      </ul>
      </section>

</section>

<section id="tips"><title>Trucs et astuces</title>

    <p>En plus des points évoqués sur la page des 
    <a href="../dns-caveats.html#tips">problèmes liés au DNS</a>, 
    voici quelques points intéressants&nbsp;:</p>

    <ul>
      <li>Toujours positionner les définitions relatives au serveur 
      principal avant toute définition <code>VirtualHost</code>. 
      (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.)</li>

      <li>Toujours regrouper les définitions <code>NameVirtualHost</code> 
      et <code>VirtualHost</code> dans la configuration pour une 
      meilleure lisibilité.</li>

      <li>Éviter les <code>ServerPaths</code> qui sont préfixes 
      d'autres <code>ServerPaths</code>. 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. (<em>par exemple</em>, 
      "ServerPath /abc" est à spécifier après  "ServerPath /abc/def").</li>
    </ul>

</section>
</manualpage>

