Créer son premier script CGI en Rebol


Le but de cet article est de vous familiariser avec la notion de script CGI en Rebol. Vous verrez qu'il est très facile de réaliser un premier script Rebol dès que vous disposez d'un serveur et que vous avez installé une version de Rebol. Vous apprendrez ainsi à dynamiser vos pages HTML, mais aussi à les enrichir et les rendre interactives par l'incorporation de code JavaScript.

Les scripts CGI : un moyen pour dynamiser les pages web

Une page web est en général une page rédigée en langage HTML. Il ne s'agit pas d'un langage de programmation, mais uniquement d'un langage de présentation standardisée des données, de façon agréable et plus ou moins structurée. Le HTML à lui tout seul ne permet pas vraiment de développer une application web.

Deux types essentiels de besoins n'ont pas de solution avec le HTML :

  • Comment afficher des données actualisées tel qu'un tableau de taille non figée ou des articles en provenance d'une base données mise à jour régulièrement ?
  • Comment traiter les données recueillies d'un formulaire : tester si le mot de passe d'un client est le bon ou enregistrer une commande d'achat ?

    Pour répondre à ces deux besoins, il a fallu compléter les pages HTML statiques avec divers types de portions de programmes, que ce soit du côté client ou du côté serveur. Les solutions sont aujourd'hui nombreuses : JavaScript, applet ou servlet Java, JSP, ASP... Mais la plus ancienne solution fût le CGI.

    Qu'est ce qu'un CGI ?

    CGI (Common Gateway Interface) signifie "Interface de passerelle commune". Un progamme CGI est un exécutable lancé du côté serveur dans le but d'effectuer des traitements de données. Le programme CGI installé sur le serveur joue le rôle de passerelle entre la requête en provenance du navigateur du client et le plus souvent une application de gestion de base de données installée sur une troisième machine (architecture n-tiers).

    Le langage de programmation des CGI est à priori quelconque, il suffit qu'il puisse être exécutable ou interprétable par le système d'exploitation du serveur, qu'il sache gérer les flux d'entrée/sortie de données, qu'il permette de manipuler les chaînes de caractères, et qu'il soit interfaçable éventuellement avec des bases de données. Parmi les langages utilisés pour réaliser des applications CGI, on peut citer classiquement le C, C++, Java ou encore des langages de script tels que Perl et Rebol.On parle alors de scripts CGI.

    Le principe de fonctionnement est simple. Un exécutable CGI est lancé par le serveur à la suite d'une requête http, et son résultat est de générer une nouvelle page web à renvoyer au navigateur afin d'être affichée. En fonction de l'extension du fichier CGI demandé (.exe, .cgi, .r, .pl, .html, ...), le serveur activera le logiciel associé pour son exécution ou son interprétation (C, C++, Java, Rebol, ...).

    Prenons l'exemple suivant. Un client saisit son login et son mot de passe en remplissant dans son navigateur le formulaire chargé avec la page HTML statique ci-dessous.

    Le code correspondant est :


    <HTML>

    <HEAD><TITLE>Ma page de connexion INDEX.HTML</TITLE></HEAD>

    <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman">

    <FORM NAME="identification" METHOD="GET" ACTION="menu.cgi">

    <DIV ALIGN="center">

    <H2>Bienvenue</H2>

    <TABLE BORDER=0 WIDTH=450>

    <TR><TD>Login</TD>

    <TD><INPUT TYPE="text" NAME="login" SIZE="20" MAXLENGTH="20"></TD></TR>

    <TR><TD>Mot de passe</FONT></TD>

    <TD><INPUT TYPE="password" NAME="motpasse"

    SIZE="20" MAXLENGTH="10" VALUE=""></TD></TR>

    </TABLE>

    <BR>

    <INPUT TYPE="submit" VALUE="Connexion">

    </DIV>

    </FORM>

    </BODY>

    </HTML>

    Lorsque l'utilisateur valide son formulaire en cliquant sur le bouton de type "submit", le serveur http répond à cette requête en exécutant le programme "menu.cgi" avec les paramètres reçus. Dans notre exemple sont utilisés deux paramètres nommés "login" et "motpasse".

    Méthode GET ou méthode POST ?

    Il existe deux méthodes de transmission de paramètres entre le client et le serveur http. Les informations saisies par le client dans le formulaire peuvent être "mises à la disposition" du script CGI : soit selon la méthode GET, soit selon la méthode POST.

    La cinquième ligne de l'exemple pourra s'écrire en fonction des deux cas :


    <FORM NAME="identification" METHOD="GET" ACTION="menu.cgi">

    ou


    <FORM NAME="identification" METHOD="POST" ACTION="menu.cgi">

    Avec la méthode GET, la transmission des paramètres se fait en utilisant l'URL et les valeurs transmises sont accessibles par le serveur via les variables d'environnement et sont visibles dans l'URL.

    Avec la méthode POST, la transmission des paramètres se fait en utilisant le périphérique d'entrée standard du serveur, les valeurs transmises sont y sont récupérées à partir du flux de données. Contrairement à la méthode précédente, la transmission des paramètres est plus discrète car les valeurs transmises ne sont plus visibles dans l'URL et la taille des informations transmises n'est pas limitée.

    Par exemple si le login saisi est la chaîne de caractères "alpha" et le mot de passe "beta", l'URL associé à la page renvoyée par le script "menu.cgi" est :

    menu.cgi?login=alpha&motpasse=beta avec la méthode GET et menu.cgi avec la méthode POST.

    Récupération des données par le serveur http

    Pour répondre à la validation du formulaire par le client, le serveur http exploite les variables d'environnement. Par exemple : pour connaître le type de la méthode utilisée (GET ou POST), le programme "script CGI" doit interroger la variable REQUEST-METHOD. Pour connaître le numéro de port auquel la requête a été envoyée, on utilise la variable d'environnement SERVER-PORT.  

    Les variables QUERY-STRING, CONTENT-LENGTH et CONTENT-TYPE, renseignent respectivement sur la chaîne d'informations transmise, sur sa longueur en nombre d'octets et sur le type de données associées selon le format MIME. Le format MIME, rappelons-le, est le mode de codage utilisé par les navigateurs afin de régler le problème d'incompatibilité lié aux caractères spéciaux, aux accents et aux caractères de ponctuation.

    Un exemple de données au format MIME est le texte récupéré par le serveur :

    menu.cgi?login=alpha&motpasse=beta.

    La règle appliquée sur le flux de sortie est q'un CGI commence toujours par préciser dans l'en-tête HTTP le type MIME pour que le navigateur sache quel type de contenu doit il afficher : fichier HTML (CONTENT-TYPE: text/html), fichier ASCII (CONTENT-TYPE: text/plain), image GIF (CONTENT-TYPE: image/gif), image JPG (CONTENT-TYPE: image/gpg), animation QUICKTIME (CONTENT-TYPE: video/quicktime), document RTF (CONTENT-TYPE: application/rtf), fichier son (CONTENT-TYPE: audio/basic)...

    A quoi ressemble un script CGI écrit en Rebol ?

    Nous supposons que votre serveur http a déjà été préalablement configuré. Qu'il s'appelle Apache, IIS ou tout simplement PWS (Personal Web Server livré gratuitement à partir de Windows98), on considère que vous avez défini un répertoire permettant la lecture et l'exécution de vos scripts CGI par le serveur : le répertoire "cgi-bin" par exemple.

    A chaque validation de formulaire, le serveur charge et exécute un script CGI.

    Notre script est un fichier exécutable (menu.cgi) écrit en langage Rebol, mais qu'est-il censé faire ?

    Après avoir récupéré les données transmises, le script doit être capable de les traiter, notamment par l'intermédiaire des manipulations d'accès à une base de données, mais pas nécessairement : un exemple de script pourrait être l'affichage d'un calendrier hebdomadaire en fonction d'une date saisie.

    Tout script CGI, par contre, est censé renvoyer comme résultat une nouvelle page qui deviendra la nouvelle page chargée dans le navigateur du client.

    Notre programme Rebol pourra ressembler à : 


    REBOL [

    title: "menu.cgi"

    description : "Mon premier script CGI en Rebol"

    ]

    ; --- Récupération des paramètres en fonction de la méthode GET ou POST utilisée dans le formulaire ---

    if error? try [

    methode: system/options/cgi/request-method

    either methode = "GET" [

    ; --- Si les données sont envoyées avec la méthode GET, on lit la variable d'environnement QUERY-STRING ---

    data: system/options/cgi/query-string

    ] [

    ; --- Si la méthode est POST, on lit le flux d'entrée sur le périphérique d'entrée standard,

    on utilise la variable CONTENT-LENGTH pour connaître le nombre d'octets que nous avons à lire ---

    data: copy ""

    len: to-integer system/options/cgi/content-length

    until [

    buffer: copy ""

    read-io system/ports/input buffer (to-integer system/options/cgi/content-length)

    append data buffer

    len: length? (head data)

    ( (length? data) = len)

    ]

    ]

    ; --- "data" contient la chaîne de caractères des données récupérées au format MIME ---

    query: make object! decode-cgi data

    ; --- Le mot "decode-cgi" de Rebol, permet de transcrire la chaîne lue en construisant un objet dont les

    propriétés sont les différents champs du formulaire ---

    ] [

    ; --- Erreur lors de la récupération des paramètres ---

    ; --- Pour débuter l'affichage de la page résultat, on doit indiquer qu'il s'agit d'une page html ---

    print "Content-Type: Text/html^/"

    ; --- Tout ce qui est écrit en sortie standard avec le mot "print" de Rebol, ira vers la page résultat ---

    print {

    <HTML>

    <HEAD></HEAD>

    <BODY BGCOLOR="#c0ffff">

    <DIV ALIGN="center">

    <H2>IMPOSSIBLE DE RECUPERER LA SAISIE DU LOGIN !</H2>

    </DIV>

    </BODY>

    </HTML>

    }

    quit ; --- Interruption de l'exécution du script ---

    ]

    ; --- Ici nous pouvons traiter les paramètres reçus dont les valeurs sont "query/login" et "query/motpasse" ---

    ; ..................................

    ; --- Ici nous pouvons définir la page à afficher

    page: {

    <HTML><HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE></HEAD>

    <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman">

    <DIV ALIGN="center">

    <H2>MENU PRINCIPAL</H2>

    <BR>

    <H5><A HREF="achat.cgi">Consulter les achats</A></H5>

    <H5><A HREF="vente.cgi">Consulter les ventes </A></H5>

    <H5><A HREF="reserver.cgi?login=MON_LOGIN">Réserver</A></H5>

    <A HREF="index.html"><IMG SRC="gif/reconnexion.jpg"></A>

    </DIV>

    </BODY>

    </HTML>

    }

    ; --- Affichage de la page résultat ---

    print "Content-Type: Text/html^/"

    print page

    La page générée ressemblera alors à :

     

    Comment intégrer du code JavaScript au sein d'un CGI ?

    Nous voulons maintenant enrichir notre script "menu.cgi" en lui incorporant une portion de code JavaScript, dans le but d'afficher une boîte de dialogue indiquant que la saisie est correcte pour le login et le mot de passe, et ceci à la fin du chargement de la page menu.

    La fonction JavaScript permettant de le faire est "alert()". Il suffit de l'appeler dans un bloc "<SCRIPT>...</SCRIPT>" de la page HTML.

    La déclaration de la page à afficher deviendra : 


    page: {

    <HTML>

    <HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE></HEAD>

    <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman">

    <DIV ALIGN="center">

    <H2>MENU PRINCIPAL</H2>

    <BR>

    <H5><A HREF="achat.cgi">Consulter les achats</A></H5>

    <H5><A HREF="vente.cgi">Consulter les ventes </A></H5>

    <H5><A HREF="reserver.cgi?login=MON_LOGIN">Réserver</A></H5>

    <A HREF="index.html"><IMG SRC="gif/reconnexion.jpg"></A>

    </DIV>

    </BODY>

    <!-- Ligne insérée -->

    <SCRIPT LANGUAGE="javascript"> alert("Connexion réussie.") </SCRIPT>

    </HTML>

    }

    Le résultat de cette modification est l'apparition à l'écran de la boite suivante :

    On peut rende cette page encore plus interactive. On va pour cela y intégrer 6 cases à cocher (balise HTML <CHECKBOX>). Chacune des cases peut être saisie séparément, mais nous souhaitons pouvoir cocher ou décocher les 6 cases en un seul clic sur un bouton "Tout cocher" ou un bouton "Tout décocher".

    Nous avons besoin de passer par un formulaire qui englobera l'ensemble des champs INPUT : CHECKBOX (cases à cocher) et BUTTON (boutons). Les 3 options de menus ne sont plus des liens HREF, elles deviennent aussi des boutons INPUT. Le script "traiter_choix.cgi"permettra après validation de traiter les cases cochées en fonction de l'option de menu choisie. Notre page est rendue un peu plus interactive par l'association de deux fonctions JavaScript "cocher()" et "decocher()" aux événements clic sur le bouton "Tout cocher" et sur "Tout décocher". Vous constaterez que la déclaration de ces fonctions apparaît dans le bloc <HEAD> car tout appel d'une fonction JavaScript doit être précédé par sa déclaration.

    Enfin, une autre forme d'exemple d'utilisation de code JavaScript est la portion nous permettant d'afficher la date et l'heure (en rouge) dans le menu.

    La description de la page affichée est transformée et devient :


    page: {

    <HTML><HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE>

    <!-- Déclaration des fonctions JavaScript -->

    <SCRIPT LANGUAGE="javascript">

    // -- Ma fonction cocher()

    function cocher()

    {

    MonFormulaire.c1.checked = true ;

    MonFormulaire.c2.checked = true ;

    MonFormulaire.c3.checked = true ;

    MonFormulaire.c4.checked = true ;

    MonFormulaire.c5.checked = true ;

    MonFormulaire.c6.checked = true ;

    }

    // -- Ma fonction decocher()

    function decocher()

    {

    MonFormulaire.c1.checked = false ;

    MonFormulaire.c2.checked = false ;

    MonFormulaire.c3.checked = false ;

    MonFormulaire.c4.checked = false ;

    MonFormulaire.c5.checked = false ;

    MonFormulaire.c6.checked = false ;

    }

    </SCRIPT>

    </HEAD>

    <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman">

    <DIV ALIGN="center">

    <H2>MENU PRINCIPAL</H2>

    <H3><FONT COLOR="red">

    Nous sommes le

    <!-- Code JavaScript pour affichage de la date du jour -->

    <script language="JavaScript">

    var aujourd_hui = new Date();

    document.write(aujourd_hui.getDate()+' ');

    document.write(aujourd_hui.getMonth()+1+'/');

    document.write(aujourd_hui.getFullYear());

    </script>

    - il est

    <!-- Code JavaScript pour affichage de l'heure -->

    <script language="JavaScript">

    var monHeure = new Date();

    document.write(monHeure.getHours()+'h ');

    document.write(monHeure.getMinutes()+'mn ');

    </script>

    </FONT></H3>

    <BR>

    <!-- Les options de menu sont englobées dans un formulaire et traitées par un seul script "traiter_choix.cgi" -->

    <FORM NAME="MonFormulaire" METHOD="POST" ACTION="traiter_choix.cgi">

    <!-- Tableau des cases à cocher -->

    <TABLE BORDER=1 BGCOLOR="cyan">

    <TR><TD COLSPAN=2 BGCOLOR="white" ALIGN=center>

    <FONT SIZE=4>Sélection du type d'immobilier</FONT></TD>

    </TR>

    <TR><TD><INPUT TYPE="checkbox" NAME="c1">Appartement</TD>

    <TD><INPUT TYPE="checkbox" NAME="c2">Bingalot</TD>

    </TR>

    <TR><TD><INPUT TYPE="checkbox" NAME="c3">Garage</TD>

    <TD><INPUT TYPE="checkbox" NAME="c4">Local commercial</TD>

    </TR>

    <TR><TD><INPUT TYPE="checkbox" NAME="c5">Maison, villa</TD>

    <TD><INPUT TYPE="checkbox" NAME="c6">Terrain</TD>

    </TR>

    <TR><TD COLSPAN=2 ALIGN=center><FONT SIZE=4>

    <!-- Association des fonctions JavaScript à l'événement clic sur le bouton INPUT -->

    <INPUT TYPE="button" VALUE="Tout cocher" ONCLICK=cocher()>

    <INPUT TYPE="button" VALUE="Tout décocher" ONCLICK=decocher()>

    </FONT></TD>

    </TR>

    </TABLE>

    <BR>

    </FORM>

    <BR>

    <!-- Les 3 options de menus ne sont plus des liens HREF mais des boutons INPUT -->

    <INPUT TYPE="button" NAME="achat" VALUE="Consulter les achats">

    <INPUT TYPE="button" NAME="vente" VALUE="Consulter les ventes">

    <INPUT TYPE="button" NAME="reserve" VALUE="Réservation">

    <BR><BR><BR>

    <A HREF="index.html"><IMG SRC="reconnexion.jpg"></A>

    </DIV>

    </BODY>

    <!-- Ligne insérée précédemment -->

    <SCRIPT LANGUAGE="javascript">alert("Connexion réussie.")</SCRIPT>

    </HTML>

    }

    Voici ce que générera le programme entier "menu.cgi" sous un navigateur :

    Conclusion

    En définitive, on pourra dire que le choix de Rebol en tant que langage de script CGI vous permettra de dynamiser vos pages Web tout en bénéficiant des avantages du langage Rebol... Si vous programmez en Rebol, vous les connaissez déjà :

  • simplicité de programmation,
  • concision du code source,
  • richesse et expressivité du langage,
  • manipulation naturelle des réseaux et des protocoles,
  • facilités d'accès aux bases de données...

    Les inconvénients par contre, sont ceux que l'on reproche aux script CGI de manière générale, à savoir :

  • la non persistance des informations lors de la navigation entre deux pages, le lien se fait soit par le passage de paramètres, soit par l'intermédiaire des cookies,
  • un trafic et une charge machine importants,
  • le fait de devoir faire attention à la sécurité.

    A vous de vous amusez maintenant... 

    Quelques liens pratiques

    Rebol :

  • http://www.rebol.com (Site officiel, en anglais)
  • http://www.rebolforces.com (Autre site Rebol, très riche, en anglais)

    CGI :

  • http://www.commentcamarche.net/cgi/cgiintro.php3 (Interfaces CGI)

    HTML :

  • http://web.avo.fr/chenu/courhtml/somrhtml.htm (Guide HTML)
  • http://www.w3.org (The World Wide Web Consortium, en anglais)
  • http://www.chez.com/manager/index.html (Comment créer et faire connaître votre site web)
  • http://www.commentcamarche.net/html/intro.php3 (Apprendre le HTML 3.0)
  • http://www.commentcamarche.net/html4/css.php3 (Nouveautés du HTML 4.0)

    JavaScript :

  • http://perso.wanadoo.fr/chatinais/coursjs/somrjs.htm (Guide JavaScript)
  • http://www.commentcamarche.net/jscript/intro.php3 (Programmation en JaScript)


    Noureddine Akhamlich

    nakhamlich@multimania.com

    Retour