Ceux d'entre vous qui ont passé les 12 derniers mois sur une île déserte n'ont probablement aucune idée de ce qu'est le Web (*). Mais la pluspart des autres s'est certainement déjà essayée à écrire quelque lignes d'HTML. Une des applications les plus attrayantes du Web est son utilisation comme interface d'accès à des données externes au Web comme les bases de données ou à des applications système. Un des mécanismes utilisès pour créer ces interfaces sont les CGI, acronyme de "Common Gateway Interface".
Un exemple trivial
#!/bin/perl print "Content-type: text/html\n\n"; print <<"EOmyPage"; <TITLE>"Hello World!" Page</TITLE> <H1>HELLO WORLD!</H1> EOmyPageLa première ligne de ce script imprime l'entête qui détermine le type du document suivant l'entête. Dans ce cas nous indiquons qu'il s'agit d'un document HTML. Il est nécessaire qu'une ligne blanche suive l'entête (remarquez à ce sujet les deux
\n
). Le reste du
programme n'est rien d'autre que le texte du document. Arrivé à ce
point vous vous dites sans doute "C'est simple comme bonjour !" et
vous avez raison. Il n'y a rien de trés mystérieux dans l'utilisation
des CGI.
#!/bin/perl print "Content-type: text/html\n\n"; $visitors = 'cat countfile'; $visitors++; if (open(OUT, "> countfile")) { print OUT $visitors; close(OUT); print <<"EOmyPage"; <TITLE>Welcome</TITLE> Hello visitor number $visitors. EOmyPage } else { print "Sorry, an error occurred\n"; }Notez bien que votre serveur HTTP tourne certainement sous l'identité d'un utilisateur particulier qui n'a pas acces aux fichiers de votre système. (Essayez toujours de confiner votre serveur dans l'espace d'un compte sans priviléges, comme "nobody" et surtout ne luis donnez JAMAIS les droits du super utilisateur). Vérifiez donc bien que les fichiers que le CGI manipule ont des droits d'accès nécessaires à votre serveur.
Ce n'est jamais une bonne idée d'interrompre brutalement un programme
CGI au milieu de son exécution. N'oubliez pas que vous avez un
correspondant à l'autre bout de la connexion et qu'il s'attend à
recevoir une réponse. C'est pourquoi le programme ci-dessus envoie un
message d'erreur quand open()
échoue plutôt que d'appeler
die()
comme c'est généralement le cas avec les scripts
PERL.
Gardez également présent à l'esprit que vous pouvez manipuler la
sortie d'autres programmes depuis votre CGI. Dans l'exemple ci-dessus,
nous avons utilisé la commande UNIX cat
pour lire le
contenu d'un fichier, mais les CGI vous permettent d'augmenter la
richesse des informations disponibles sur le Web en publiant le
résultat d'autres programmes. Par exemple, voici un petit CGI qui
affiche la liste des processus tournant sur la machine où il s'exécute
en utilisant le résultat de ps
. (On pourait facilement
imaginer que ceci est une des pieces d'une panoplie d'outils de
diagnostiques à distance d'un grans réseau).
#!/bin/perl print "Content-type: text/plain\n\n"; if (open(PS, "ps -ef |")) { while (<PS>) { print; } } else { print "An error occurred\n"; }Remarquez que nous avons utilisé une type de contenu différent
Content-type
. Le type "plain text" est généralement
affiché par les browsers dans une police de taille fixe (Courier) en
préservant les espaces ce qui n'est pas le cas avec le type
"html". Pour ceux qui connaissent HTML, l'affichage aura le style
qu'il aurait eu s'il avait été enclos dans un bloc
<PRE>
.
Vous pouvez appeler n'importe quel autre programme. Vous pouvez
l'interfacer avec n'importe lequel des services réseau comme WAIS,
gopher et même NNTP ( et si nous avions un lecteur de news
multi-threadé sur le Web ? (***) ). Vous pouriez
interfacer une partie des bases d'information de votre société et
proposer un annuaire téléphonique ou permetre aux gens de consulter
leurs profits via le Web. Faites cependant attention aux aspects de
sécurité avant de vous lancer dans de grandes avantures. Vous n'avez
certainement pas envie de donner l'accès à la planète entière à
l'intégralité de vos données. Même l'exemple du ps
ci-dessus peut donner plus d'informations que vous ne l'auriez
souhaité.
#!/bin/perl print "Content-type: text/plain\n\n"; foreach $var (sort keys %ENV) { print "\$ENV{$var} = '$ENV{$var}'\n"; }Par exemple, les variables
REMOTE_HOST
et
REMOTE_ADDR
donnent le nom entièrement qualifié et
l'adresse IP de la machine connectée à votre serveur HTTP. Â
"Netmarket" on nous demande souvent "Mais comment faites vous cela" à
propos de notre "home page" qui affiche un message "Merci de vous connecter
depuis $ENV{'REMOTE_HOST'}
".
Le browser client peut également donner des information à votre
serveur HTTP. Le serveur les transmettra à son tour au CGI au travers
de variables d'environnement dont le nom est préfixé par
HTTP_
. En particulier, le client donnera une chaîne
d'indentification comme NCSA Mosaic for the X Window System/2.4
libwww/2.12 modified
dans la variable
HTTP_USER_AGENT
. Malheureusement, il n'y a pas de
standard pour passer des informations depuis le client. Aussi est-il
impossible d'identifier à coup sur la nature du browser de votre
correspondant encore que ce soit possible pour les plus usuels.
Mais pourquoi donc se préocuper de la nature de browser ? N'oubliez pas que les anciens browsers peuvent ne pas supporter les derniers rafinements des spécification HTML. Par exemple, vous ne voudriez pas envoyer une table à un Mosaic Version 2.4 par ce qu'il ne saurait pas les interpreter, de même que vous ne n'enverez pas un images à un browser textuel comme Lynx car son utilisateur ne pourrait pas la voir (****).
<TITLE>Send Us Email!</TITLE> We'd love to hear from you. Enter your email address and comments in the spaces provided and we'll respond as quickly as we can!<P> <FORM METHOD="POST" ACTION="bin/process_form"> Your E-mail address<BR> <INPUT NAME="email" SIZE=45 MAXLENGTH=45><BR> Your Message<BR> <TEXTAREA NAME="comments" ROWS=12 COLS=45></TEXTAREA><P> <INPUT TYPE="submit" VALUE="Send your comments"> </FORM>Le tag
<FORM ... ACTION=" ... ">
indique le nom du
programme que le serveur doit exécuter aprés que les informations
auront été envoyées. Cette forme crée un champ pour saisir l'adresse
électronique et une zône de saisie libre pour entrer le message. Le
bouton Send your comments
permet à l'utilisateur
d'envoyer l'information.
Lorsque l'utilisateur appuie sur le bouton Send your comments
button
, le browser regroupe toutes les infomrations et les
envoies au serveur HTTP avec une demande d'exécution du programme
spécifié dans <FORM ... ACTION=" ... ">
. La façon
dont le programme récupère ces informations dépend du tag
<FORM ... METHOD=" ... ">
. Dans l'exemple ci
dessus, nous avons utilisé POST
. Ceci signifie que les
informations doivent être lues par le CGI sur son entrée
standard. Vous devez vous attendre à recevoir un bloc d'informations
dont la taille est donnée par la variable d'environnement
CONTENT_LENGTH
. La méthode la plus simple pour lire cette
information est d'utiliser la fonctionread()
:
#!/bin/perl read(STDIN,$stuff $ENV{`CONTENT_LENGTH'}); . . .Maintenant il ne vous reste plus qu'à exploitabler les informations. Elles sont livrées en une suite d'égalités de la forme
nom=valeur
séparées par un &. Les noms sont des
chaînes quelconque que vous spécifiez dans la forme en utilisant le
tag <... NAME=" ... "...>
. Dans l'exemple ci
dessus, le nom de l'adresse electronique est email
et le
message comments
. Il faut également savoir que les blancs
sont traduits en +
et que les caractères non
alphabétiques sonf convertis en %<hed>
où
<hex>
représente la valeur hexadécimale de leur
code ASCII. Le traitement typique d'une forme commence par ;nbsp;:
#!/bin/perl read(STDIN, $stuff, $ENV{'CONTENT_LENGTH'}); @pairs = split(/\&/, $stuff); for (@pairs) { ($field, $val) = split(/=/); $field =~ s/\+/ /g; $field =~ s/%(\w\w)/sprintf("%c", hex($1))/eg; $val =~ s/\+/ /g; $val =~ s/%(\w\w)/sprintf("%c", hex($1))/eg; $entries{$field} = $val; } ...Nous commencons par lire l'ensemble des données sur l'entrée standard puis nous les découpons en une liste d'égalitées
nom=valeur
. Ensuite nous traitons chaque égalité en
séparant le nom de la valeur, puis nous convertissons les
+
et &hex
en leur caracter
originaux. N'essayez pas de substituer en une fois la chaîne lue sur
l'entrée standard car certains drapaux de codage peuvent être des
& ou des =
. Substituez toujours en premier les
+
en espace car certain des caracters codés par
&hex
peuvent être des blancs.Maintenant que vous avez distribué l'intégralité des données dans un tableau associatif, vous pouvez faire ce que bon vous semble avec elles. N'oubliez pas de retourner une notification à votre correspondant aprés le traitement de sa forme :
print "Content-type: text/html\n\n"; if (open(MAIL, "| /usr/lib/sendmail webmaster")) { print MAIL <<"EOdoc"; From: The Comments Page <webmaster> To: webmaster Subject: Comments Mail Mail from: $entries{"email"} $entries{"comments"} EOdoc close(MAIL); print <<"EOpage"; <TITLE>Thanks!</TITLE> Thanks for taking the time to send us comments!<P> We will be responding promptly.<P> EOpage } else { print <<"EOpage"; <TITLE>Bummer!</TITLE> We encountered an error trying to send your comments.<P> Please send mail to <I>webmaster\@netmarket.com</I><P> EOpage }Soyez TRÈS attentif à ce que vous faites des données que vous récupérer d'une forme. Souvenez-vous que votre correspondant peut saisir n'IMPORTE QUOI et peut causer des dégâts considérables si vous ne vous méfiez pas. N'utilisez même pas une chaîne de la forme dans une commande que vous exécuteriez dans votre CGI. Notez que je ne passe même pas l'adresse du correspondant dans le champ
From
parce qu'elle pourrait contenir une commande
sendmail dans le cas ou le mail rebondirait.
Des exemples simples de CGI sont dispobible partout sur le Web (NCSA propose une archive d'exemple pour vous aider à commencer)
Traduction de ;login: Vol. 20 No. 4, août 1994
* World Wild Web (www), la toile d'araignée mondiale (ndtr).
** Nous n'arrivons pas à nous accommoder de la
pédanterie qui veut que tous les termes techniques soient
traduits. Aussi continurons nous à utiliser le terme de browser au lieu
de buttineur et autre brouteur de toile. (ndtr)
*** A l'époque où Hal écrivait ces lignes, les
outils du web n'étaient pas encore aussi développés qu'aujourd'hui et
M$ n'avait pas encore inventé l'INTERNET. (ndtr)
**** A cette époque le WEB n'était encore fréquenté
que par des gens policés qui se souciaient d'économiser la bande
passante et de pouvoir inter-opérer avec la concurrence. Mais bon, M$
n'avait pas encore inventé l'INTERNET. (ndtr)
Dernière édition: 4 avril 1997 phb Original 11/27/96 |
|