# Apache et les variables d'environnement

Le serveur HTTP Apache permet de conserver et d'utiliser certaines informations dans des variables appelées variables d'environnement. Ces informations peuvent servir à contrôler divers paramètres tels que la journalisation ou le contrôle d'accès. Ces variables sont également utilisées pour communiquer avec d'autres programmes, comme les scripts CGI. Ce document traite des manières de manipuler et de tirer parti de ces variables.

Bien qu'elles soient appelées variables d'environnement, il ne s'agit pas de variables d'environnement contrôlées par le système d'exploitation. Ces variables sont conservées, et manipulées suivant des mécanismes internes à Apache. Elles sont transformées en véritables variables d'environnement (au sens système) seulement quand elles doivent être passées à des scripts CGI ou à des scripts 'Server Side Includes'. Pour manipuler l'environnement du système d'exploitation sur lequel tourne un serveur Apache, il suffit d'utiliser les méthodes standard fournies par l'interpréteur de commandes du système d'exploitation.

# Définir les variables d'environnement

mod_env
mod_rewrite
mod_setenvif
mod_unique_id
BrowserMatch
BrowserMatchNoCase
PassEnv
RewriteRule
SetEnv
SetEnvIf
SetEnvIfNoCase
UnsetEnv

## Manipulations simples de l'environnement

La méthode la plus simple pour définir une variable d'environnement dans Apache est d'utiliser la directive SetEnv. Les variables peuvent également être chargées depuis l'interpréteur de commandes à partir duquel le serveur a été démarré, au moyen de la directive PassEnv.

## Paramétrage selon les requêtes

Dans un but de souplesse, les directives que mod_setenvif permet d'utiliser sont ajustables en fonction de certaines caractéristiques des requêtes parvenant au serveur. Par exemple, il est possible de définir une variable seulement si la requête provient d'un certain type de navigateur (User-Agent), ou bien si un champ Referer bien précis est trouvé. Une souplesse encore plus grande est offerte par la directive RewriteRule du module mod_rewrite qui accepte le paramètre `[E=...]` pour définir des variables d'environnement.

## Identifiants uniques

Enfin, la variable d'environnement `UNIQUE_ID` est créée par mod_unique_id pour chaque requête, de manière à être unique et donc représentative de chaque requête.

## Variables CGI standard

En plus de toutes les variables d'environnement définies dans la configuration d'Apache et celles du système d'exploitation, les spécifications CGI demandent que certaines variables d'environnement contenant des informations propres à la requête soient toujours passées aux scripts CGI et aux pages SSI.

## Problèmes possibles

- Il n'est pas possible de remplacer la valeur des variables CGI standard au moyen des directives qui manipulent les variables d'environnement.
- Dans les cas où les scripts CGI sont lancés au moyen de suexec, l'environnement est nettoyé et les variables sont initialisées avec des valeurs sûres, définies lors de la compilation de `suexec.c`.
- Pour des raisons d'interopérabilité, les noms des variables d'environnement ne peuvent être constitués que de lettres, de chiffres et du caractère de soulignement '_'. De plus, le premier caractère du nom ne peut pas être un chiffre. Les caractères en contradiction avec ces règles sont remplacés par des caractères de soulignement avant que les variables ne soient transmises aux scripts CGI ou aux pages SSI.

# Utilisation des variables d'environnement

mod_access
mod_cgi
mod_ext_filter
mod_headers
mod_include
mod_log_config
mod_rewrite
Allow
CustomLog
Deny
ExtFilterDefine
Header
LogFormat
RewriteCond
RewriteRule

## Scripts CGI

Une des principales utilisations des variables d'environnement est l'envoi d'informations aux scripts CGI. Comme précisé ci- avant, l'environnement passé aux scripts CGI contient des informations standard au sujet de la requête en plus de toutes les variables initialisées au travers de la configuration d'Apache. Pour plus de détails, consultez le tutorial CGI.

## Pages SSI

Les documents analysés par le serveur (documents SSI), gérés par le filtre `INCLUDES` de mod_include, peuvent demander l'affichage de variables d'environnement au moyen de l'élément `echo`, et peuvent les utiliser pour personnaliser des pages en fonctions de certaines caractéristiques de la requête. Apache permet aussi l'utilisation de pages SSI avec les variables d'environnement standard CGI comme discuté ci-avant. Consultez le tutorial SSI pour plus d'informations.

## Contrôle d'accès

Les droits d'accès au serveur peuvent être contrôlés au moyen de variables d'environnement en utilisant les directives `allow from env=` et `deny from env=`. Celles ci, utilisées avec SetEnvIf, permettent un contrôle d'accès au serveur très souple en fonction de caractéristiques propres au client. Par exemple, il est possible d'utiliser ces directives pour refuser l'accès au serveur à certains navigateurs (User-Agent).

## Journalisation sous certaines conditions

Les variables d'environnement peuvent être enregistrées dans le journal des accès ('access log') au moyen de l'option `%e` de LogFormat. De plus, la décision d'enregistrer ou non certaines requêtes peut être prise en fonction des variables d'environnement au moyen de la directive CustomLog. Cette méthode, utilisée avec la directive SetEnvIf, permet un contrôle très souple de l'enregistrement des requêtes. Par exemple, il est possible de ne pas garder de trace des requêtes demandant des noms de fichiers se terminant par `gif`, ou de n'enregistrer que les requêtes des clients situés hors du sous-réseau auquel appartient le serveur.

## Personnaliser les en-têtes des réponses HTTP

La directive Header peut tirer parti de l'existence ou non d'une variable d'environnement afin de choisir d'inclure certains en-têtes HTTP dans la réponse retournée au client. Ceci permet, par exemple, d'envoyer un certain en-tête de réponse seulement si un en-tête similaire a été positionné dans la requête émanant du client.

## Activation des filtres externes

Il est possible d'utiliser une variable d'environnement pour activer les filtres externes (gérés par mod_ext_filter au moyen de la directive ExtFilterDefine) grâce aux options `disableenv=` et `enableenv=`.

## Réécriture d'URL

La forme `%{ENV:...}` de TestString, dans la directive RewriteCond, permet au moteur de réécriture de mod_rewrite d'utiliser les variables d'environnement pour contrôler les réécritures. Notez que toutes les variables internes à mod_rewrite, accessibles sans le préfixe `ENV:`, ne sont pas des variables d'environnement d'Apache. Elles sont uniquement propres à mod_rewrite et ne peuvent pas être utilisées par d'autres modules.

# Variables d'environnement spéciales

Certains problèmes liés à l'interopérabilité ont conduit à la mise en place de mécanismes spéciaux, qui modifient le fonctionnement d'Apache selon le type des clients auxquels il répond. Afin de garantir la plus grande souplesse possible, ces mécanismes sont contrôlés par des variables d'environnement spéciales, telles que BrowserMatch, bien qu'on puisse également utiliser SetEnv et PassEnv par exemple.

## downgrade-1.0

Ceci oblige Apache à traiter la requête comme du HTTP/1.0 même si elle a été construite sur une norme plus récente.

## force-no-vary

Ceci provoque l'effacement de tous les champs `Vary` de l'en-tête de réponse avant qu'il ne soit envoyé au client. Certains clients interprètent mal ce champ (voir les problèmes avec certains clients), et initialiser cette variable peut permettre de résoudre ce problème. Cette variable requiert également l'utilisation de force-response-1.0.

## force-response-1.0

Ceci oblige Apache à n'envoyer que des réponses en HTTP/1.0 aux clients réalisant une requête en HTTP/1.0. Cette fonction a été implémentée au départ pour résoudre un problème avec les serveurs mandataires d'AOL. Certains clients HTTP/1.0 réagissent mal quand ils reçoivent une réponse en HTTP/1.1, ce qui peut poser des problèmes d'interopérabilité avec eux.

## gzip-only-text/html

Si cette variable est positionnée avec une valeur de "1", le filtre de sortie DEFLATE du module mod_deflate se retrouve désactivé pour les documents dont le type mime n'est pas `text/html`.

## no-gzip

Si cette variable est initialisée, le filtre `DEFLATE` du module mod_deflate est totalement désactivé.

## nokeepalive

Si cette variable est initialisée, les fonctions KeepAlive sont désactivées.

## prefer-language

Cette variable modifie le fonctionnement de mod_negotiation. Si la variable contient un marqueur de langue (comme `en`, `ja` ou `x-klingon`), le module mod_negotiation va tenter de fournir une réponse dans cette langue parmi les variantes possibles. Si aucune de ces variantes n'existe, une négociation normale aura lieu.

## redirect-carefully

Cette variable rend le serveur plus attentif quand il doit envoyer une redirection au client. Cette variable est habituellement utilisée quand un client a un problème connu pour gérer les redirections. Cette variable a été implémentée pour pallier à un problème du logiciel WebFolders de Microsoft qui ne sait pas gérer correctement les redirections vers les répertoires via les méthodes DAV.

## suppress-error-charset

Existe depuis la version 2.0.40

Quand Apache envoie une redirection en réponse à une requête, la réponse contient un message à afficher par le client, au cas où il ne peut suivre automatiquement la redirection. Le fonctionnement par défaut d'Apache est d'écrire ce texte avec le jeu de caractère qu'il utilise, c'est à dire ISO-8859-1.

Cependant, si la redirection pointe vers une page présentant un jeu de caractères différent, certains navigateurs buggés utilisent le jeu de caractères du texte de la redirection, au lieu de celui de la page qu'ils affichaient. De ce fait, un texte en grec serait mal affiché.

Si cette variable d'environnement est utilisée, Apache n'indiquera pas le jeu de caractère dans le texte de la redirection, ce qui permet à ces navigateurs d'afficher correctement la page de destination.

# Exemples

## Modifier le fonctionnement d'un protocole pour les clients qui le gèrent mal

Il est conseillé de placer les lignes suivantes dans httpd.conf afin de gérer des problèmes connus de certains clients.

    #
    # Les directives ci-après modifient le fonctionnement standard de HTTP.
    # La première directive désactive les fonctions keepalive pour les
    # navigateurs disant s'appeler 'Netscape 2.x'
    # Il existe des problèmes connus avec ces navigateurs.
    # La deuxième directive gère Internet Explorer 4.0b2 de Microsoft qui
    # n'implémente pas correctement HTTP/1.1 et qui ne supporte pas les
    # fonctions keepalive quand la réponse du serveur contient des codes 301
    # ou 302 (redirections)
    #
    BrowserMatch "Mozilla/2" nokeepalive
    BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0

    #
    # Les directives ci-dessous désactivent HTTP/1.1 pour les navigateurs qui
    # violent les spécifications HTTP/1.0, en ne sachant pas analyser des
    # réponses basiques en HTTP/1.1.
    #
    BrowserMatch "RealPlayer 4\.0" force-response-1.0
    BrowserMatch "Java/1\.0" force-response-1.0
    BrowserMatch "JDK/1\.0" force-response-1.0

## Ne pas enregistrer les requêtes pour des images dans le journal des accès

Cet exemple montre comment ne pas enregistrer les requêtes à destination d'images dans le journal des accès. Il est facile de le modifier, pour limiter l'enregistrement à certains répertoires, ou pour des requêtes venant de machines précises.

    SetEnvIf Request_URI \.gif image-request
    SetEnvIf Request_URI \.jpg image-request
    SetEnvIf Request_URI \.png image-request
    CustomLog logs/access_log common env=!image-request

## Empêcher le « vol d'images »

Cet exemple montre comment empêcher le chargement d'images de votre serveur depuis des pages qui ne sont pas hébergées sur celui-ci. Cette configuration n'est pas conseillée, mais elle peut être utile dans certaines circonstances. Il est supposé ici que toutes les images sont stockées dans le répertoire /web/images.

    SetEnvIf Referer "^http://www.example.com/" local_referal
    # Autorise les navigateurs qui n'envoient pas de champ Referer
    SetEnvIf Referer "^$" local_referal
    <Directory /web/images>
       Order Deny,Allow
       Deny from all
       Allow from env=local_referal
    </Directory>

Pour plus d'informations sur cette technique, consultez le tutorial ApacheToday « Keeping Your Images from Adorning Other Sites ».