Programmation des Sites Web

Deuxième Année ENSIMAG

ENSIMAG 2000 - 2001

James L. Crowley

Séance 4

27 octobre 2000

Plan :

CGI : Common Gateway Interface

Le "Common Gateway Interface" est un protocole qui permet au page html

d'exécuter les programmes. Ceci autorise les possibilités illimitées aux pages html.

Common : Utilisable dans tous les systèmes d'exploitation et avec tous les langages de programmation.

Gateway : CGI dans accès aux services

Interface : CGI est un protocole formellement spécifié.

Formulaires HTML


On peut exécuter un script à partir d'un page html via l'usage d'un formulaire.

Syntaxe de la balise FORM : <FORM ACTION ="script.cgi" METHOD="get">

Les scripts cgi sont installés dans un répertoire cgi-bin du serveur.

..[serveur]/cgi-bin/script.cgi

L'ENSIMAG a fait un lien "soft" dans le cgi-bin vers chaque membre du cours : cgi-bin/jlc -> ~jlc/cgi-bin.
Il faut que les programmes en cgi-bin soient executable par tout le monde!

Fait le commande :

cd cgi-bin // aller au repertoire
chmod a+x * // all have access executable

Exécution d'un script par une ficher HTML

Exemple d'un script CGI appelé par href

Soit le script s4.1.cgi installé en cgi-bin.

#!/usr/local/bin/perl

#file s4.1.cgi

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>Current Users</TITLE>" , "\n";

print "<BODY>" , "\n";

print `who`; # le commande "who" est executee

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

la ligne "print `who`;" fait appelle à la commande Unix, "who".

La sortie de "who" au STDOUT.

Le html du formulaire s4.0.html:

<HTML>

<TITLE>Who is logged in? </TITLE>

<BODY BGCOLOR=#FFFFFF >

<H1>Who is logged on?</H1>

<A HREF="/cgi-bin/jlc/s4.1.cgi"> Who</A> is logged on

</FORM>

</BODY>

</HTML>

 

On peut utiliser "href" ou "form" pour appeler le script.

La différence est dans le passage de paramètres.

Les paramètres sont codés :?arg=value&arg=value

Exemple : /cgi-bin/jlc/s4.1.cgi?arg=value&arg=value

Avec des formulaires, la chaîne de caractères des paramètres sont composées automatiquement.

S'on utilise "href" , il faut construire une chaîne de caractères codés pour les paramètres.

Exemple d'un script CGI appelé par un formulaire

L'html du formulaire s4.1.html

<HTML>

<TITLE>Qui est sur la systeme ?</TITLE>

<BODY BGCOLOR=#FFFFFF >

<FORM ACTION ="/cgi-bin/jlc/s4.1.cgi" METHOD="get">

<H1>Who is logged on?</H1>

<INPUT TYPE=SUBMIT Value="Who">

</FORM>

</BODY>

</HTML>

Note le "?" a la fin de l'appel. http://ensisun.imag.fr/cgi-bin/jlc/s4.1.cgi?

Passage des Paramètres aux SCRIPTs : GET et POST

Il y a deux méthodes de passage des paramètres aux scripts :

GET les données sont transmises par avec la requête à l'URL.

POST les données sont envoyées et lues via STDIN.

Méthode GET ou POST ?

GET

POST

Passage des Paramètres avec GET

File s4.2.html

<HTML>

<TITLE>Exemple d'une Forme</TITLE>

<BODY BGCOLOR=#FFFFFF >

<FORM ACTION ="/cgi-bin/s4.2.cgi" METHOD="get">

<H1>Veuillez completer ce formulaire</H1>

<P>Nom: <input name="name" size="48">

<br>

<INPUT TYPE=SUBMIT Value="Valider">

<INPUT TYPE=RESET Value="Reinitialiser">

</FORM>

</BODY>

</HTML>

avec le script s4.2.cgi

#!/usr/local/bin/perl

#file name s4.2.cgi

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>s4.2.cgi</TITLE>" , "\n";

print "<BODY>" , "\n";

$query_string = $ENV{'QUERY_STRING'};

print "Script called with $query_string", "\n";

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

La requête est :

http://ensisun.imag.fr/cgi-bin/s4.2.cgi?name=Jim+Crowley

La chaîne "name=Jim+Crowley" est retourné par la variable d'environnement

"'QUERY_STRING';

La variable de l'environnement QUERY-STRING contient

une chaîne avec tous les paramètres, avec la forme :

cle=value.

Value est limité à la lettre et nombre.

Les variables d'environnement sont accessibles via $ENV{...}

Environnement du serveur

Les programmes du CGI disposent d'un nombre important de variable d'environnement .

(avec le format protocole://NomServeur:port/path )

QUERY_STRING Chaîne de caractères caractérisant la requête

Exemple d'accès aux variables d'environnement

#!/usr/local/bin/perl

# file s4.3.cgi

print "Content-Type: text/html", "\n\n";

print "<HTML>", "\n";

print "<HEAD> <TITLE>Environnement du serveur</TITLE> </HEAD>", "\n";

print "<HR><PRE>", "\n";

print "Server Name: ", $ENV{'SERVER_NAME'}, "<BR>", "\n";

print "Running on port: ", $ENV{'SERVER_PORT'}, "<BR>", "\n";

print "Server Software",$ENV{'SERVER_SOFTWARE'}, "<BR>", "\n";

print "Server Protocol",$ENV{'SERVER_PROTOCOL'}, "<BR>", "\n";

print "Adresse IP de la machine du serveur: ", $ENV{'HTTP_HOST'}, "<BR>", "\n";

print "Repertoire contenant le serveur", $ENV{'DOCUMENT_ROOT'}, "<BR>", "\n";

print "Adresse IP de la machine cliente", $ENV{'REMOTE_ADDR'}, "<BR>", "\n";

print "Adresse symbolique de la machine cliente: ", $ENV{'REMOTE_HOST'},"<BR>","\n";

print "Login de la personne effectuant la requete:",$ENV{'REMOTE_IDENT'},"<BR>", "\n";

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

Avec le page html : s4.3.html

<HTML>

<TITLE>Echo les Variables d'Environement</TITLE>

<BODY BGCOLOR=#FFFFFF >

<H1>Les Variables de l'Environement</H1>

<p>

Les <A HREF="/cgi-bin/s4.3.cgi">Variables</A>

de l'environement.

<br>

</FORM>

</BODY>

</HTML>

Codage des Paramètres

1. Les caractères non ASCII (code > 128) sont remplacés par %xx ou xx est le code ASCII.

2. Les caractères réservés sont remplacés par leur code ASCII. Ils sont :

< > " # % ! $ \ & ( ) + = } [ ] \ : ; ~ ? , / [TAB]

3. L'espace est remplacé par le signe +

4. Les pairs noms/valeur sont transformés par la chaîne de caractères : nom=valeur

5. Les différentes chaînes de caractères sont contaminées en insérant le symbole & entre les paires : nom1=valeur1&nom2=valeur2&...

Voici un script PERL pour convertir une chaîne a une chaîne codée pour CGI:

#!/usr/local/bin/perl

print "String to encode: ";

$string = <STDIN>;

chop($string);

string =~ s/(\W)/sprintf("%%%x", ord($1))/eg;

print "Encoded String: ";

print $string, "\n";

exit(0);

On peut décoder les lignes avec une substitution en PERL.

La syntaxe d'une substitution est tr/vieux/nouvelle/

#!/usr/local/bin/perl

print "String to decode: ";

$string = <STDIN>;

chop($string);

$string =~ tr/+/ /;

$string =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C", hex($1))/eg;

print "Decoded String: ";

print $string, "\n";

exit(0);

Extraction des paramètres

En PERL, on peut convertir les chaînes de la forme nom=valeur dans

une "hash" ou "nom" est la clé et "valeur" est la valeur avec une commande

"split:". Syntaxe : (clé, valeur) = split( /char/, $chaine);

Par exemple :

$query_string = $ENV{'QUERY_STRING'};

($field_name, $command) = split(/=/, $query_string);

 

#!/usr/local/bin/perl

#file s4.4.cgi

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>Execution d'un commande unix</TITLE>" , "\n";

print "<BODY>" , "\n";

$query_string = $ENV{'QUERY_STRING'};

print "query_string : $query_string.<BR>", "\n";

($field, $value) = split(/=/, $query_string);

print "field = $field.<br>value= $value. <br>", "\n";

print "<br>", "\n";

print "<br>", "\n";

print `$value`;

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

avec s.4.4.html

<HTML>

<TITLE>Commandes UNIX</TITLE>

<BODYBGCOLOR=#FFFFFF >

<FORM ACTION ="/cgi-bin/jlc/s4.4.cgi" METHOD="get">

<H1>Executer un commande UNIX</H1>

<br>

<P>Commande: <input name="commande" size="48">

<br>

<INPUT TYPE=SUBMIT Value="Valider">

<INPUT TYPE=RESET Value="Reinitialiser">

</FORM>

</BODY>

</HTML>

S'il y a des arguments, il faut aussi les décoder avec

$form_info =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C", hex($1))/eg;

Exemple :

s4.5.html : Exécuter une commande à partir d'un formulaire.

<HTML>

<TITLE>Commandes UNIX</TITLE>

<BODYBGCOLOR=#FFFFFF >

<FORM ACTION ="/cgi-bin/s4.5.cgi" METHOD="get">

<H1>Executer un commande UNIX</H1>

<P>Commande: <input name="commande" size="48">

<br>

<INPUT TYPE=SUBMIT Value="Valider">

<INPUT TYPE=RESET Value="Reinitialiser">

</FORM>

</BODY>

</HTML>

s4.5.cgi :

#!/usr/local/bin/perl

# File name s4.5.cgi

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>Execution d'un commande unix</TITLE>" , "\n";

print "<BODY>" , "\n";

#get the query string and decode it

$query_string = $ENV{'QUERY_STRING'};

print "query = $query_string<br>", "\n";

$query_string =~ tr/+/ /; #substitute " " for "+"

$query_string =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C", hex($1))/eg;

print "query = $query_string<br>", "\n";

#split the query string at "="

($field_name, $command) = split(/=/, $query_string);

print "Execution du commande : $command", "\n";

print "<br>", "\n";

print "<br>", "\n";

print `$command`;

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

L'exemple suivant permet d'exécuter une logicielle ou commande Unix

a partir d'un page web:

Attn. Ceci peut être TRES dangereux. L'utilisateur peut taper "rm -r *"

ou bien n'importe quel autre commande.

Les commandes sont exécutées avec une priorité de root!

 

 

Passage des Paramètres avec POST

Avec POST, il faut lire la réponse par STDIN.

En PERL, ceci se fait par :

$size = $ENV{'CONTENT_LENGTH'};

read (STDIN, $query_string, $size};

exemple : s4.6.html

<HTML>

<TITLE>Exemple d'une Forme</TITLE>

<BODY BGCOLOR=#FFFFFF >

<H1>Veuillez completer ce formulaire</H1>

<FORM ACTION ="/cgi-bin/s4.6.cgi" METHOD="POST">

<P>Nom: <input name="name" size="48">

<br>

<INPUT TYPE=SUBMIT Value="Valider">

<INPUT TYPE=RESET Value="Reinitialiser">

</FORM>

</BODY>

</HTML>

s4.6.cgi

#!/usr/local/bin/perl

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>s4.6.cgi</TITLE>" , "\n";

print "<BODY>" , "\n";

$size = $ENV{'CONTENT_LENGTH'};

read (STDIN, $query_string, $size);

print "Script called with $query_string <p>", "\n";

print "Size of query_string is $size.", "\n";

print "query string is $query_string<br>", "\n";

$query_string =~ tr/+/ /; #substitute " " for "+"

$query_string =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C", hex($1))/eg;

print "decode of query : $query_string<br>", "\n";

#split the query string at "="

($field_name, $command) = split(/=/, $query_string);

print "Execution du commande : $command", "\n";

print "<br>", "\n";

print "<br>", "\n";

print `$command`;

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

Accommodation de GET et POST.

La choix de méthode (GET ou POST) est disponible dans la variable

d'environnement : "REQUEST_METHOD".

On peut écrire des scripts qui acceptent les deux méthodes GET et POST.

$method = $ENV{'REQUEST_METHOD'};
if ($method eq "GET")
{
} elseif ($method eq "POST")
{
} else
{
}

Exemple :

#!/usr/local/bin/perl

#file s4.7.cgi

print "Content-type: text/html", "\n\n";

print "<HTML>" , "\n";

print "<TITLE>s4.7.cgi</TITLE>" , "\n";

print "<BODY>" , "\n";

$method = $ENV{'REQUEST_METHOD'};

if ($method eq "GET")

{

$query = $ENV{'QUERY_STRING'};

} elsif ($method eq "POST")

{

$size = $ENV{'CONTENT_LENGTH'};

read (STDIN, $query_string, $size);

} else

{

&return_error(500, "Server Error", "Unsupported Method");

}

print "Script called with query_string: $query", "\n";

print "</BODY>" , "\n";

print "</HTML>" , "\n";

exit(0);

 

exemple : s4.7.html

<HTML>

<TITLE>Exemple d'une Forme</TITLE>

<BODY BGCOLOR=#FFFFFF >

<H1>Veuillez completer ce formulaire</H1>

<FORM ACTION ="/cgi-bin/jlc/s4.7.cgi" METHOD="GET">

<P>Nom: <input name="name" size="48">

<br>

<INPUT TYPE=SUBMIT Value="Valider">

<INPUT TYPE=RESET Value="Reinitialiser">

</FORM>

</BODY>

</HTML>