<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Recettes et tutoriels

Tutoriel Apache : Contenu dynamique basé sur CGI

Langues Disponibles:  en  |  es  |  fr  |  ja  |  ko 

Support Apache!

Voir aussi

top

Introduction

CGI (Common Gateway Interface) définit une méthode d'interaction entre un serveur web et des programmes générateurs de contenu externes, plus souvent appelés programmes CGI ou scripts CGI. Il s'agit d'une méthode simple pour ajouter du contenu dynamique à votre site web en utilisant votre langage de programmation préféré. Ce document est une introduction à la configuration de CGI sur votre serveur web Apache, et une initiation à l'écriture de programmes CGI.

top

Configurer Apache pour autoriser CGI

Apache doit être configuré pour permettre l'exécution des programmes CGI, pour que vos programmes CGI puissent fonctionner correctement. Il existe plusieurs méthodes pour y parvenir.

Note: si Apache a été compilé avec le support des modules partagés (DSO), vous devez vous assurer que le module CGI est chargé ; vous devez pour cela vérifier que la directive LoadModule correspondante n'a pas été commentée dans votre apache2.conf. Une directive correcte doit ressembler à ceci :
LoadModule cgid_module modules/mod_cgid.so
Sous Windows, ou si l'on utilise un module MPM non-threadé comme prefork, une directive correctement configurée sera du style :
LoadModule cgi_module modules/mod_cgi.so

ScriptAlias

La directive ScriptAlias indique à Apache qu'un répertoire particulier est dédié aux programmes CGI. Apache considérera que tout fichier situé dans ce répertoire est un programme CGI, et tentera de l'exécuter lorsque cette ressource fera l'objet d'une requête client.

La directive ScriptAlias se présente comme suit :

ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"

Cet exemple est tiré de votre fichier de configuration apache2.conf par défaut, si vous avez installé Apache dans son répertoire par défaut. La directive ScriptAlias est similaire à la directive Alias, qui définit à quel répertoire particulier doit correspondre un préfixe d'URL. Alias et ScriptAlias sont généralement utilisés pour accéder à des répertoires situés en dehors du répertoire défini par la directive DocumentRoot. La différence entre Alias et ScriptAlias réside dans le fait que ScriptAlias indique en plus que tout ce qui se trouve sous le préfixe d'URL doit être considéré comme un programme CGI. Ainsi, l'exemple ci-dessus indique à Apache que toute requête pour une ressource commençant par /cgi-bin/ doit être servie depuis le répertoire /usr/local/apache2/cgi-bin/, et doit être traitée en tant que programme CGI.

Par exemple, si une requête pour l'URL http://www.example.com/cgi-bin/test.pl est effectuée, Apache tentera d'exécuter le fichier /usr/local/apache2/cgi-bin/test.pl et en renverra la sortie. Bien entendu, le fichier doit exister, être exécutable, et retourner sa sortie d'une manière particulière, sinon Apache renverra un message d'erreur.

CGI en dehors des répertoires ScripAlias

Pour des raisons de sécurité, la localisation des programmes CGI est souvent restreinte aux répertoires définis par ScriptAlias. De cette manière, les administrateurs peuvent contrôler précisément qui est autorisé à utiliser les programmes CGI. Cependant, si les précautions adéquates quant à la sécurité sont prises, il n'y a aucune raison pour que les programmes CGI ne puissent pas être exécutés depuis d'autres répertoires. Par exemple, vous pouvez autoriser les utilisateurs à enregistrer des contenus web dans leurs répertoires home à l'aide de la directive UserDir. S'ils veulent mettre en oeuvre leurs propres programmes CGI, mais n'ont pas l'autorisation d'accès au répertoire cgi-bin principal, ils devront être en mesure d'exécuter ces programmes depuis un autre répertoire.

L'autorisation d'exécution des programmes CGI dans un répertoire arbitraire se fait en deux étapes. En premier lieu, le gestionnaire cgi-script doit être activé à l'aide d'une directive AddHandler ou SetHandler. En second lieu, ExecCGI doit être spécifié dans la directive Options.

Utilisation d'options explicites pour permettre l'exécution des programmes CGI

Vous pouvez utiliser de manière explicite la directive Options dans le fichier de configuration de votre serveur principal, pour indiquer que l'exécution des programmes CGI est permise depuis un répertoire particulier :

<Directory "/usr/local/apache2/htdocs/somedir">
    Options +ExecCGI
</Directory>

La directive ci-dessus indique à Apache qu'il doit permettre l'exécution des fichiers CGI. Vous devez aussi indiquer au serveur quels fichiers sont des fichiers CGI. La directive AddHandler suivante indique au serveur qu'il doit traiter tous les fichiers possédant une extension cgi ou pl en tant que programmes CGI :

AddHandler cgi-script .cgi .pl

Fichiers .htaccess

Le tutoriel .htaccess montre comment activer les programmes CGI si vous n'avez pas accès au fichier apache2.conf.

Répertoires utilisateurs

Pour permettre l'exécution en tant que programme CGI de tout fichier possédant l'extension .cgi et situé dans un répertoire utilisateur, vous pouvez utiliser la configuration suivante :

<Directory "/home/*/public_html">
    Options +ExecCGI
    AddHandler cgi-script .cgi
</Directory>

Pour indiquer un sous-répertoire cgi-bin d'un répertoire utilisateur où tout fichier sera traité en tant que programme CGI, vous pouvez utiliser ceci :

<Directory "/home/*/public_html/cgi-bin">
    Options ExecCGI
    SetHandler cgi-script
</Directory>
top

Ecrire un programme CGI

Il y a deux différences principales entre la programmation "standard" et la programmation CGI.

En premier lieu, toute sortie de votre programme CGI doit être précédée d'un en-tête MIME-type. Il s'agit d'un en-tête HTTP qui indique au client quel type de contenu il reçoit. La plupart du temps, il se présente comme suit :

Content-type: text/html

En second lieu, votre sortie doit être en HTML, ou tout autre format qu'un navigateur est en mesure d'afficher. La plupart du temps, il s'agira de HTML, mais occasionnellement, vous pouvez être amené à écrire un programme CGI qui renvoie une image gif, ou un autre type de contenu non-HTML.

A part ces deux différences, un programme CGI ressemblera à tout autre programme que vous pourriez être amené à écrire.

Votre premier programme CGI

L'exemple suivant est un exemple de programme CGI qui permet d'afficher une ligne de caractères dans votre navigateur. Ecrivez ce qui suit, enregistrez le dans un fichier nommé premier.pl, et placez le dans votre répertoire cgi-bin.

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";

Même si Perl ne vous est pas familier, vous devriez être capable de comprendre le fonctionnement de ce programme. La première ligne indique à Apache (ou à toute interface à partir de laquelle le programme s'exécute) que ce programme peut être exécuté en fournissant son fichier à l'interpréteur /usr/bin/perl. La seconde ligne affiche la déclaration du type de contenu considéré, suivie de deux paires "Retour chariot - Nouvelle ligne". Ceci a pour effet d'insérer une ligne vide après l'en-tête pour marquer la fin des en-têtes HTTP, et le début du corps du document. La troisième ligne affiche la chaîne de caractères "Bonjour tout le monde . . .". Et c'est tout ce dont vous avez besoin.

Si vous ouvrez votre navigateur favori et lui indiquez l'adresse

http://www.example.com/cgi-bin/premier.pl

ou toute autre URL correspondant à votre programme CGI, Vous verrez la ligne Bonjour tout le monde . . . s'afficher dans la fenêtre de votre navigateur. Ce n'est pas extraordinaire, mais si vous y êtes parvenu, vous avez de bonnes chances d'y parvenir pour tout autre programme plus sophistiqué.

top

Mais ça ne marche toujours pas !

Vous devriez voir au moins une des quatre sorties suivantes dans votre navigateur lorsque vous essayez d'accéder à votre programme CGI depuis le web :

Le flux de sortie de votre programme CGI
Impeccable ! Cela signifie que tout fonctionne correctement. Si la sortie est correcte mais n'est pas traitée correctement par le navigateur, assurez-vous d'avoir défini Content-Type de manière appropriée dans votre programme CGI.
Le code source de votre programme CGI ou un message "POST Method Not Allowed"
Cela signifie que vous n'avez pas configuré Apache de manière à ce qu'il puisse traiter votre programme CGI. Relisez la section sur la configuration d'Apache, et essayez de trouver votre erreur.
Un message commençant par "Forbidden"
Ce type de message est révélateur d'un problème de droits. Consultez le journal des erreurs d'Apache et la section ci-dessous sur les droits des fichiers.
Un message contenant "Internal Server Error"
Si vous consultez le journal des erreurs d'Apache, vous y trouverez probablement des messages du type "Premature end of script headers" (Fin prématurée des en-têtes de script), éventuellement accompagnés d'un message d'erreur généré par votre programme CGI. Dans ce cas, il va vous falloir lire chacune des sections ci-dessous pour déterminer ce qui empêche votre programme CGI de générer les en-têtes appropriés.

Droits des fichiers

Souvenez-vous que le serveur ne s'exécute pas sous votre nom. En d'autres termes, lorsque le serveur a démarré, il s'exécute avec les droits d'un utilisateur non privilégié - en général nobody, ou www - et en conséquence, il aura besoin de droits supplémentaires pour pouvoir exécuter des fichiers dont vous êtes le propriétaire. En général, pour qu'un fichier ait des droits suffisants pour être exécutable par nobody, il suffit de lui attribuer des droits d'exécution pour tout le monde :

chmod a+x premier.pl

En outre, si votre programme doit pouvoir accéder en lecture et/ou écriture à d'autres fichiers, ces derniers devront avoir les droits appropriés.

Chemin des exécutables (PATH) et variables d'environnement

Lorsque vous lancez un programme depuis la ligne de commande, certaines informations sont passées au shell sans que vous vous en doutiez. Par exemple, la variable PATH indique au shell où il doit rechercher les exécutables auxquels vous faites référence.

Lorsqu'un programme s'exécute depuis le serveur web en tant que programme CGI, sa variable PATH n'aura peut-être pas la même valeur. Tout programme que vous invoquez dans votre programme CGI ( comme par exemple sendmail) devra être spécifié par son chemin complet, de façon à ce que le shell puisse le trouver lorsqu'il tentera d'exécuter votre programme CGI.

Un exemple typique de spécification de programme est le chemin vers l'interpréteur de script (souvent perl) que l'on trouve à la première ligne de votre programme CGI et qui va ressembler à ceci :

#!/usr/bin/perl

Assurez-vous qu'il s'agit bien du chemin correct vers l'interpréteur.

Lors de l'édition de scripts CGI sous Windows, il se peut que des caractères de fin de ligne soient ajoutés au chemin de l'interpréteur. Assurez-vous donc que les fichiers sont bien transmis au serveur en mode ASCII. Dans le cas contraire, l'OS pourra envoyer des avertissements "Command not found" à cause des caractères de fin de ligne non reconnus car considérés comme faisant partie du nom de fichier de l'interpréteur.

Variables d'environnement manquantes

Si votre programme CGI dépend de variables d'environnement non standards, vous devrez vous assurez que ces variables lui sont bien transmises par Apache.

Lorsque des en-têtes HTTP ne sont pas transmis à l'environnement, assurez-vous qu'ils sont bien formatés selon la RFC 2616, section 4.2 : les noms d'en-têtes doivent commencer par une lettre, elle-même suivie de lettres, chiffres ou traits d'union. Tout en-tête dont le nom viole cette règle sera ignoré.

Erreurs inhérentes au programme

La plupart des échecs dans l'exécution d'un programme CGI proviennent du programme lui-même. Ceci est particulièrement vrai lorsque ce satané programme CGI se bloque, alors que vous avez appris à ne plus commettre les deux erreurs précédentes. La première chose à faire est de vous assurer que votre programme s'exécute depuis la ligne de commande, avant de le tester à partir du serveur web. Par exemple, essayez :

cd /usr/local/apache2/cgi-bin
./premier.pl

(N'invoquez pas l'interpréteur perl. Le shell et Apache doivent être capable de le déterminer à partir de l'information sur le chemin située sur la première ligne du script.)