Introduction au CGI (Common Gateway Interface)
5. Les entrées sorties
La communication en entrée peut se faire via des variables d'environnement ou directement via l'entrée
standard (STDIN), La sortie se fait via la sortie standard (STDOUT) sur laquelle on envoie les informations à afficher sous forme identifiée.
Nous y reviendrons à la fin de cette section.
Voici une liste d'un certain nombre de 'variables d'environnement' accessibles par un programme CGI.
5.1 Variables d'environnement
5.1.1 Variables relatives à la requête
- CONTENT_LENGTH :
- Taille en octets du contenu des informations jointes à la requête en mode PUT ou POST, vide si on utilise la méthode GET.
- CONTENT_TYPE :
- Type MIME des données envoyées au programme CGI appelé par la méthode POST, vide si on utilise la méthode GET.
- QUERY_STRING :
- Chaîne de caractères au format URL contenant les paramètres joints à la requête GET.
Contient les données d'entrée du programme précédé du caractère '?'.
Elle est vide si on utilise la méthode POST, a moins qu'il y ait déjà quelque chose derrière l'URL du script.
- REQUEST_METHOD :
- Contient la méthode utilisée pour la requête (GET, POST, HEAD, PUT, DELETE, LINK), sert pour
déterminer la méthode utilisée pour traiter les données.
5.1.2 Variables relatives à la connexion client-serveur
On appelle client HTTP, le programme utilisateur qui fait la requête, en général c'est
un nanigateur.
- HTTP_ACCEPT :
- Les différents types MIME supportés par le client HTTP (Format: type/soustype).
- HTTP_ACCEPT_LANGUAGE :
- Langage utilisé par le client HTTP.
- HTTP_ACCEPT_ENCODING :
- Type d'encodage supporté par le client HTTP.
- HTTP_ACCEPT_CHARSET :
- Table de caractères supportée par le client HTTP.
- HTTP_COOKIE :
- Liste des 'Cookies' associés par le client HTTP à la ressource consultée.
- HTTP_USER_AGENT :
- Signature du client HTTP effectuant la requête (Format: software/version ou library/version).
- HTTP_REFERER :
- URL de la ressource ayant renvoyé le client HTTP sur la requête en cours.
- REMOTE_ADDR :
- Adresse IP de l'ordinateur client effectuant la requête. Cette variable permet de
repérer, d'identifier des ordinateurs et d'effectuer quelque chose en conséquence (empêcher l'accès, donner des
droits supplémentaires par exemple).
- REMOTE_HOST :
- Adresse DNS (nom de domaine) de l'ordinateur client effectuant la requête. Cette variable est
très utilisée pour afficher des publicités en rapport avec le pays d'origine par exemple.
- REMOTE_USER :
- Identifiant de l'utilisateur du client, lorsque le mode d'authentification de la ressource est actif.
- AUTH_TYPE :
- Si le serveur supporte l'authentification et que le script est protégé, indique le protocole utilisé pour valider l'identité.
- REMOTE_PORT :
- Port utilisé par le client HTTP pour cette connexion. Souvent absente
5.1.3 Variables relatives au serveur :
- DOCUMENT_ROOT :
- Nom du répertoire physique contenant la racine du serveur consulté sur la machine.
- GATEWAY_INTERFACE :
- La version du standard CGI supportée par le serveur HTTP (Format: CGI/révision).
- HTTP_HOST ou SERVER_NAME :
- Adresse IP ou DNS de la machine hébergeant le serveur HTTP.
- SERVER_ADMIN :
- Adresse e-mail déclarée par l'administrateur du serveur.
- SCRIPT_NAME :
- URL du chemin d'accès au script CGI.
- SCRIPT_FILENAME :
- Nom et chemin d'accès complet au CGI sur le disque du serveur consulté.
- SERVER_PORT :
- Port sur lequel le serveur a réceptionné la requête
- SERVER_PROTOCOL :
- Nom et version du protocole utilisé par le serveur HTTP (Format: protocol/révision).
- SERVER_SOFTWARE
- Nom et version du logiciel serveur HTTP utilisé. (Format nom/version)
- TZ :
- Nom de la 'Time Zone' définie sur la machine du serveur HTTP.
5.2 Les entrées sorties standards
5.2.1 L'entrée standard
On appel méthode la façon de passer les informations du serveur au programme CGI.
Elles définissent la façon dont le programme reçoit les données.
Il faut différencier 2 méthodes :
- La méthode GET :
- Quand on utilise cette méthode, le programme reçoit les données dans la variable d'environnement QUERY_STRING.
La méthode GET ne peut être utilisée que si les données d'entrées ne sont pas trop importantes, ni confidentielle car cette méthodes
passe les arguments dans l'URL donc visible, de plus la longueur d'une URL est
est limitée à 1024 caractères.
- La méthode POST :
- Quand on utilise cette méthode, les données à traiter sont transmises via l'entrée standard (STDIN). Le serveur n'indiquant pas la
fin de la chaîne avec un caractère spécial, il faut utiliser la variable d'environnement CONTENT_LENGTH pour
connaître la longueur des données.
Dans les 2 cas les données sont transmises sous forme URL-encoded; c'est-à-dire que les espaces sont remplacés par des signes
+, les tildes (~) sont remplacés par %7E et ainsi de suite...
5.2.2 La sortie standard
Le programme CGI envoie les résultats vers la sortie standard (STDOUT soit l'écran en général). Ils peuvent être
envoyés directement vers le client HTTP ou être interprétés par le serveur qui va effectuer une nouvelle action.
Dans les résultats renvoyés, le serveur cherche un des 3 en-têtes que le programme peut retourner :
- Content-type :
- Indique le type MIME des données. Généralement comme les programmes CGI renvoient de l'HTML,
la ligne utilisée est Content-type: text/html\n\n. Attention à bien mettre les 2 nouvelles lignes (\n)
- Location :
- Indique au serveur que l'on fait référence à un autre document. Utilisé pour faure des redirections.
- Status :
- C'est le code d'état renvoyé par le serveur au client. Format : nnn XXXXXXX où nnn est un nombre à 3 chiffres
et XXXXXX le texte qui y correspond. Exemple : 404 Not found.
5.3 Récupération des informations
Nous venons de voir la théorie, maintenant voici des exemples concrets.
Même si ces exemples sont simples, la méthode est applicable à partout.
Pour vous eviter de recopier ces programmes, chargez-les :
http://www.ftls.org/fr/initiation/cgi/exemples.tar.gz.
5.3.1 Les formulaires
5.3.1.1 Méthode GET
<FORM ACTION="/cgi-bin/monscript.cgi" METHOD="GET"><BR>
Name : <INPUT TYPE="text" NAME="Name"><BR>
E-Mail : <INPUT TYPE="text" NAME="Mail"><BR>
<INPUT TYPE="submit" Value=" Test "><BR>
</FORM>
5.3.1.2 Méthode POST
<FORM ACTION="/cgi-bin/monscript.cgi" METHOD="POST"><BR>
Name : <INPUT TYPE="text" NAME="Name"><BR>
E-Mail : <INPUT TYPE="text" NAME="Mail"><BR>
<INPUT TYPE="submit" Value=" Test "><BR>
</FORM>
5.3.2 En Shell
#!/bin/sh
#
if [ "$REQUEST_METHOD" = "POST" ]; then
read QUERY_STRING
RECU="STDIN (Methode POST)"
else
RECU="QUERY_STRING (Methode GET)"
fi
# On remplace les & par des ' ', découpe la chaine de donnees en des paires name=value
OPTS=`echo $QUERY_STRING | sed 's/&/ /g'`
echo "Content-type: text/html"
echo ""
echo "<HTML><HEAD><TITLE>Resultat</TITLE></HEAD>"
echo "<BODY BGCOLOR=\"#FFFFFF\">"
echo "<H1>Résultat du traitement du formulaire</H1>"
echo "<H2>Chaine de données reçue par le CGI</H2>"
echo "$RECU <B>$QUERY_STRING</B>"
echo "<H2>Liste des informations décodées</H2>"
# Récuperation et mise en forme des donnees
echo "<UL>"
for opt in $OPTS
do
NAME=`echo $opt
| sed 's/=/ /g'
| awk '{print $1}'`
VALUE=`echo $opt
| sed 's/=/ /g'
| awk '{print $2}'
| sed 's,%,\\\x,g'
| sed 's/+/ /g'`
echo "<LI><B>$NAME: </B>$VALUE"
done
echo "</UL>"
echo "</BODY></HTML>"
5.3.3 En C
On remarque dans cette exemple que l'on utilise la fonction 'getenv("Nom Variable")'
pour récupérer les variables d'environnements. En C le traitement
des chaînes de caractères étant moins aisé l'ajout de cette partie
alourdirait considérablement l'exemple pour rien. Il est à noter qu'il existe
une bibliothèque 'cgi-util' permettant de simplifier considérablement la récupération
des informations, voir second exemple.
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
int c;
printf("Content-type: text/html\n\n");
printf("<HTML><HEAD><TITLE>Resultat</TITLE></HEAD>\n");
printf("<BODY BGCOLOR=\"#FFFFFF\">\n");
printf("<H1>Résultat du traitement du formulaire</H1>\n");
printf("<H2>Chaine de données reçue par le CGI</H2>");
/* verification des variables d'environnement */
if (strcmp (getenv("REQUEST_METHOD"),"POST") == 0) {
printf("STDIN (Methode POST) <B>");
while((c=getchar()) != EOF) {
printf("%c" ,c);
}
printf("</B>");
}
if (strcmp(getenv("REQUEST_METHOD"),"GET") == 0) {
printf("QUERY_STRING (Methode GET) <B>%s</B>",
getenv("QUERY_STRING"));
}
printf("<H2>Liste des informations décodées</H2>");
printf("Non traitée dans cet exemple...");
printf("</BODY></HTML>\n");
}
En utilisant la bibliothèque 'cgi-util'.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cgi-util.h"
#define STRLEN 1024
main(int argc, char *argv[])
{
char name[STRLEN];
char mail[STRLEN];
printf("Content-type: text/html\n\n");
printf("<HTML><HEAD><TITLE>Resultat</TITLE></HEAD>\n");
printf("<BODY BGCOLOR=\"#FFFFFF\">\n");
printf("<H1>Résultat du traitement du formulaire</H1>\n");
printf("<H2>Chaine de données reçue par le CGI</H2>");
printf("Non traitée dans cet exemple...");
/* Initialise CGI */
cgiinit();
/* Recupération des informations */
getentry(name, "Name");
getentry(mail, "Mail");
printf("<H2>Liste des informations décodées</H2>");
printf("<UL><LI>Name : %s", name);
printf("<LI><B>E-Mail: </B>%s</UL>", mail);
printf("</BODY></HTML>\n");
}
5.3.4 En Perl
On remarque dans cette exemple que les valeurs sont stockées dans le tableau associatif '%ENV', on utilise '$ENV{"Nom Variable"}'
pour récupérer la variable d'environnement. Il est à noter qu'il existe
des bibliothèques 'cgi-lib' permettant de simplifier considérablement la récupération
des informations, voir second exemple.
#!/usr/bin/perl
# Récupération des informations
if ($ENV{'REQUEST_METHOD'} eq "POST" ) {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
$Recu="STDIN (Methode POST)" }
else {
$Recu="QUERY_STRING (Methode GET)";
$buffer = $ENV{'QUERY_STRING'};
}
# Traitement et découpage.
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Resultat</TITLE></HEAD>\n";
print "<BODY BGCOLOR=\"#FFFFFF\">\n";
print "<H1>Résultat du traitement du formulaire</H1>\n";
print "<H2>Chaine de données reçue par le CGI</H2>\n";
print "$Recu <B>$buffer</B>\n";
print "<H2>Liste des informations décodées</H2>\n";
print "<UL>\n";
foreach $match (keys (%FORM)) {
print "<LI><B>$match: </B>".$FORM{$match};
}
print "</UL>\n";
print "</BODY></HTML>\n";
En utilisant la bibliothèque 'cgi-lib'.
#!/usr/bin/perl
require "cgi-lib.pl";
# Récupération des informations
&ReadParse(*FORM);
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Resultat</TITLE></HEAD>\n";
print "<BODY BGCOLOR=\"#FFFFFF\">\n";
print "<H1>Résultat du traitement du formulaire</H1>\n";
print "<H2>Chaine de données reçue par le CGI</H2>\n";
print "Non traitée dans cet exemple...\n";
print "<H2>Liste des informations décodées</H2>\n";
print "<UL>\n";
foreach $match (keys (%FORM)) {
print "<LI><B>$match: </B>".$FORM{$match};
}
print "</UL>\n";
print "</BODY></HTML>\n";
En utilisant le module CGI.
#!/usr/bin/perl -w
use CGI;
use strict;
# Création de l'objet CGI
my $query_cgi = new CGI;
print $query_cgi->header; # "Content-type: text/html\n\n";
print $query_cgi->start_html(
-title => 'Résultat',
-bgcolor => '#FFFFFF');
print $query_cgi->h1('Résultat du traitement du formulaire');
print $query_cgi->h2('Chaine de données reçue par le CGI');
print "Non traitée dans cet exemple...\n";
print $query_cgi->h2('Liste des informations décodées<');
print "<UL>\n";
foreach ($query_cgi->param) {
print "<LI><B>$_:</B> ".$query_cgi->param($_);
}
print "</UL>\n";
print $query_cgi->end_html;
|