Introduction à la notion de script pour le Web
gilles.hunault@univ-angers.fr
Un script CGI est un fichier exécutable, comparable à un programme classique. Le résultat de son exécution est une page web à contenu variable, contrairement à une page web de base dont le contenu est fixe. Si vous cliquez sur le mot fixe vous avez toujours la même page Web qui apparait, à savoir le texte "CECI EST UNE PAGE FIXE".
cliquez ici pour voir le contenu de cette page.
Par contre, si vous cliquez sur le mot variable la page qui apparait n'est jamais la même puisqu'elle contient la date et l'heure à la seconde près de l'instant où vous avez cliqué. Il suffit de la recharger pour vérifier que son contenu est différent.
cliquez ici pour voir le contenu de cette page.
Cette page n'est pourtant pas dynamique et son contenu reste indéfiniment celui de l'instant où elle a été chargée : ni les secondes ni les minutes ne défilent. Ce n'est pas le cas pour la page que vous pouvez obtenir en cliquant sur le mot dynamique.
cliquez ici pour voir le contenu de cette page.
Exécution des scripts
Pour qu'un fichier soit exécutable comme script CGI, il doit être dans un répertoire spécial défini par la commande ScriptAlias du fichier httpd.conf (situé souvent dans /etc/httpd/conf/ sous Linux). N'importe qui ne peut donc pas exécuter un script CGI : il faut y être autorisé.De plus chaque fichier de ce répertoire doit commencer (même sous Windows) par un "shebang" c'est à dire une indication de l'exécutable qui le lance. Par exemple nous disposons d'un fichier test.rex ; en ligne de commande, il s'exécute par x:\regina.exe test.rex pour Windows et par /usr/bin/regina test.rex sous Linux (les chemins d'accès sont importants car le serveur Web n'utilise pas le même "PATH" que les autres utilisateurs). Pour que ce fichier soit utilisable il faut donc que la première ligne du fichier test.rex soit
Pour qu'un script fonctionne, il faut aussi qu'il annonce au serveur Web ce qu'il va fournir comme "type MIME" ; pour les pages web que nous présentons, il s'agit de texte donc les deux premières lignes que le script envoie sont obligatoirement
#! x:\regina.exe si le serveur Web est sous Windows, #! /usr/bin/regina si le serveur Web est sous Linux. Il reste ensuite à envoyer le début de la page web. Par exempe, le début typique d'un script pour le web en rexx est
1. Content-type: text/html 2. (une ligne vide) #! /usr/bin/regina say 'Content-type: text/html' say '' say "" say '' say " alors que pour un script en perl, ce sera :... " say '' say ''#! /usr/bin/perl print "Content-type: text/html\n" ; print "\n" ; print "" ; print '' ; print ' Pour un script shell sous Unix, on écrira... ' ; print '' ; print '' ;#! /bin/sh echo Content-type: text/html echo Pour un fichier .bat sous Dos, il ne faut pas oublier de mettre un point après le mot echo car sinon la machine indique le mode d'echo au lieu de laisser une ligne vide. De plus, il faut commencer par un @echo off sinon les commandes sont affichées avant d'etre exécutées. On écrit donc en début de fichier :@echo off echo Content-type: text/html echo. Si on ne fournit pas les deux premières lignes pour l'identification de contenu, comme par exemple avec le script badcgi.rex alors le serveur affiche une page web qui contient le texte "Internal server error" et dans le fichier de "log" apparait le texte "Premature end of script headers".
Méthodes GET et POST
Gestion des erreursComme pour un programme classique issu d'une compilation Pascal, C, Java ou l'interprétation d'un script Awk, Rexx, Perl, on peut passer des paramètres au script. Il y a pour cela deux méthodes, nommées GET et POST qui s'utilisent diffféremment.
Avec la méthode GET, les paramètres sont visibles sur la ligne de l'URL : après le nom du script, il y a un point d'interrogation puis des couples NOM= VALEUR séparés par des symboles &. Le texte qui suit l'URL est également mis dans la variable d'environnement nommée QUERY_STRING. Ainsi l'URL http://www.demo.com/essai.cgi?nb=5&auteur=gh exécute le programme essai.cgi sur l'ordinateur qui contient le serbeur web référencé par www.demo.com et pour ce script, la variable d'environnement QUERY_STRING contient nb=5&auteur=gh ce qui signifie que pour le script la variable nb a comme a valeur 5 et la variable auteur a comme valeur "gh".
cliquez ici pour un démonstration du mode get.
cliquez ici pour voir le contenu du script.
Pour la méthode POST, on ne voit rien sur la ligne de l'URL. On doit lire sur ce qu'on appelle l'entré standard (comme si les paramètres avaient été tapés au clavier). Il faut lire exactement autant de caractères qu'indique la variable d'environnement nommée CONTENT_LENGTH car il n'y a pas d'indicateur de fin d'entrée ou de fin de fichier.
cliquez ici pour un démonstration du mode post.
cliquez ici pour voir le contenu de la page.
cliquez ici pour voir le contenu du script.
On remarquera au passage que le nom du bouton a été renvoyé ainsi qu'un champ caché (de type "hidden") nommé "oh".
Si le programme ne peut pas s'exécuter (syntaxe incorrecte du programme, erreur d'exécution...) une page d'erreur est affichée, contenant un texte proche de
Internal Server Error The server encountered an internal error or misconfiguration and was unable to complete your request. Please contact the server administrator, webmaster@localhost and inform them of the time the error occurred, and anything you might have done that may have caused the error. More information about this error may be available in the server error log.Le fichier de "log" dont il est question est le fichier errors.log qui contient la description des différentes erreurs survenues à la tentative d'exécution du script. C'est le message que l'on verrait normalement si on essayait d'exécuter "à la main" le programme. Par exemple si nous mettons le mot END en trop dans un script rexx, ce qui est incorrect et qui empêche l'exécution, le fichier de log contiendra quelque chose comme
[Sat Oct 06 15:11:52 2001] [error] [client 127.0.0.1] Error 10.1: END has no corresponding DO or SELECTVoici quelques exemples d'erreur, avec des messages parfois sybillins (nous avons coupé les lignes en deux pour plus de lisibilité).
[Sat Oct 06 12:14:27 2001] [error] [client 127.0.0.1] Error 40.11: FORMAT argument 1 must be a number; found "1+2+3" [Sat Oct 06 12:20:48 2001] [error] [client 127.0.0.1] File does not exist: c:/program files/easyphp/www/ghs/srlpano2.htm [Sat Oct 06 12:20:57 2001] [error] [client 127.0.0.1] Commande ou nom de fichier incorrect [Sat Oct 06 15:00:03 2001] [error] [client 127.0.0.1] attempt to invoke directory as script: c:/program files/easyphp/www/ghcgi [Sat Oct 06 15:00:58 2001] [error] [client 127.0.0.1] c:/program files/easyphp/www/ghcgi/cgis.htm is not executable; ensure interpreted scripts have "#!" first line [Sat Oct 06 15:00:58 2001] [error] [client 127.0.0.1] (2)No such file or directory: couldn't spawn child process: c:/program files/easyphp/www/ghcgi/cgis.htm [Sat Oct 06 15:11:52 2001] [error] [client 127.0.0.1] Premature end of script headers: c:/program files/easyphp/www/ghcgi/mget.rex [Sat Oct 06 15:11:52 2001] [error] [client 127.0.0.1] Error 10 running "c:\PROGRA~1\EASYPHP\WWW\GHCGI\MGET.REX", line 11: Unexpected or unmatched ENDLe script suivant nommé erreur.cgi permet de voir les dernières lignes de log sous Linux afin de savoir quelle est l'erreur. Pour l'utiliser, commencez par cliquer sur un script avec erreur et vérifiez que vous obtenez bien le message : "Internal server error". Allez ensuite rapidement voir dans le log avec le script erreur.cgi (rapidement car on n'affiche que les 20 dernières lignes ; s'il y a beaucoup d'erreurs, la notre ne sera pas affichée). Erreur de format pour exec(): exec of /home/info/sirius/gh/public_html/cgi-bin/badcgi.rex failed Vous devriez alors voir comme erreur quelque chose comme
[Tue Oct 9 16:46:12 2001] [error] (8)Erreur de format pour exec(): exec of /home/info/sirius/gh/public_html/cgi-bin/badcgi.rex failed [Tue Oct 9 16:46:12 2001] [error] [client 172.20.41.2] Premature end of script headers:Comme ce script ne fonctionne en standard que le serveur du département informatique de la faculté des Sciences de l'Université d'Angers, si vous recopiez ces scripts via l'archive des scripts, vous devrez peut-être plutot utiliserEnfin, le script suivant essaie de trouver le fichier de log, que la machine soit sous Windows ou sous Linux :
varLog au cas où error_log serait dans /var/log/httpd/ optWeb au cas où error_log serait dans /opt/web/logs/
cliquez ici pour passer à la page "Programmes pour le web"