Common Gateway Interface Questions pour une architecture client-serveur Comment un client peut envoyer des données vers un serveur ? Comment générer dynamiquement une page HTML ? Constat sur le format HTML Le contenu d’une page HTML est statique (même si on ajoute quelques petites animations sympathiques) Intérêt des CGI (Common Gateway Interface) Permettre une personnalisation du contenu d’un document HTML ou d’effectuer un traitement sur des données envoyées par un client, en corrélation ou pas avec d’autres données connues du serveur uniquement (ex : base de données/connaissances)
Common Gateway Interface
Common Gateway Interface Le protocole HTTP (Hyper Text Transfert Protocol) Permet la communication entre des clients et un serveur à travers le réseau Internet, sous une forme intelligible Est un protocole à état, c’est à dire que chaque connexion est indépendante de la précédente et que le protocole ne permet pas de mémoriser un quelconque élément d’un dialogue Ceci est particulièrement gênant pour certaines applications qui aimeraient savoir s’ils ont affaire avec un client déjà rencontré ou d’autres qui nécessitent un « dialogue » de plusieurs échanges La commande GET Requête du client (sur le port 80 d’une machine serveur) GET hello.html Réponse du serveur <HTML> <BODY bgcolor=#FFFFFO> <B>Hello, World !</B> </BODY> </HTML>
Common Gateway Interface Protocole HTTP et mise en œuvre des CGI Le client envoie une commande GET au serveur Le serveur HTTP identifie le paramètre comme un exécutable Le serveur exécute le CGI et attend une réponse de celui-ci Le CGI retourne au processus père un flot de caractères Le serveur vérifie qu’il s’agit bien de HTML (Content-Type:text/html) Le serveur retourne la page HTML au client
Common Gateway Interface La commande GET vers un CGI Requête du client GET cgi-bin/hello.cgi Code source en langage C du CGI hello.cgi Réponse du serveur <HTML> <BODY bgcolor=#FFFFFO> <B>Hello, World !</B> </BODY> </HTML> #include <stdio.h> int main(void) { printf("Content-TYPE: text/html\n\n"); printf("<HTML>\n<BODY bgcolor=#FFFFFO>\n"); printf("<B>Hello, World !</B>\n"); printf("</BODY>\n</HTML>\n"); }
Common Gateway Interface Les formulaires en HTML Permet de saisir et de transmettre des données vers le serveur Exemple de page HTML avec formulaire : <HTML> <HEAD><TITLE>Exemple de formulaire</TITLE></HEAD> <BODY bgcolor=#FFFFFO> <CENTER> <B>CGI Multiplicateur</B> <P><EM>Entrez deux valeurs :</EM> <FORM action="cgi-bin/mult.cgi" method="GET"> <INPUT name="x" size="5"> <INPUT name="y" size="5"> <INPUT type="submit" value="MULTIPLIER"> </FORM> </CENTER> </BODY> </HTML>
Common Gateway Interface Commande GET vers un CGI avec paramètres Requête du client GET cgi-bin/mult.cgi?x=2&y=3 Réponse du serveur <HTML> <HEAD><TITLE>Multiplication</TITLE></HEAD> <BODY> <H3>Résultat de la multiplication :</H3> <P>Le produit de 2 et 3 est 6. </BODY> </HTML> Comment le CGI récupère t-il les paramètres x et y ? Le serveur a affecté deux variables d’environnement La variable REQUEST_METHOD contient la méthode invoquée : "GET" La variable QUERY_STRING contient les données : "x=2&y=3" Il suffit d’extraire les valeurs de x et de y dans la chaîne de caractères En langage C, on peut utiliser la fonction sscanf (voir page suivante)
Common Gateway Interface Code source en langage C du CGI mult.cgi #include <stdio.h> #include <stdlib.h> int main(void) { char *data; long x,y; printf("Content-TYPE: text/html\n\n"); printf("<HTML>\n<HEAD><TITLE>Multiplication</TITLE></HEAD>\n"); printf("<BODY>\n<H3>Résultat de la multiplication :</H3>\n"); data = getenv("QUERY_STRING"); if(data == NULL) printf("<P>Erreur : Problème lors du passage des données\n"); else if(sscanf(data, "x=%ld&y=%ld", &x, &y)!=2) printf("<P>Erreur : Données invalides (ne sont pas numériques)\n"); else { printf("<P>Le produit de %ld et %ld est %ld.\n", x, y, x*y); printf("</BODY>\n</HTML>\n"); }
Common Gateway Interface Une autre commande HTTP : la commande POST Les données parviennent au CGI via l’entrée standard (stdin) Les données sont codées exactement comme pour le GET Exemple de formulaire HTML associé à une méthode POST <HTML> <HEAD><TITLE>Méthode POST</TITLE></HEAD> <BODY> <FORM action="cgi-bin/getenv.cgi" method="POST"> <INPUT type= "hidden" name="cache" value="7"> <INPUT name="texte" size="40"> <INPUT type="radio" name="radio1">radio1 <INPUT type="radio" name="radio2">radio2 <INPUT type="submit"> </FORM> </BODY> </HTML>
Common Gateway Interface Aspect du formulaire chez le client : Comment le CGI récupère t-il les paramètres ? Le serveur a affecté trois variables d’environnement : La variable REQUEST_METHOD contient la méthode : "POST" La variable CONTENT_LENGTH contient la taille des données : 30 La variable CONTENT_TYPE contient le type des données : "application/x-www-form-urlencoded" Le buffer de stdin contient les données : "cache=7&texte=coucou&radio1=on"
Common Gateway Interface Réponse du CGI : Code source en langage C du CGI getenv.cgi #include <stdio.h> #define DATALEN 256 int main(void) { char data[DATALEN]; fgets(data, DATALEN, stdin); printf("Content-TYPE: text/html\n\n"); printf ("<HTML><HEAD><TITLE>Variables</TITLE></HEAD><BODY>\n"); printf ("<BR>REQUEST_METHOD : %s\n", getenv("REQUEST_METHOD")); printf ("<BR>CONTENT_TYPE : %s\n", getenv("CONTENT_TYPE")); printf ("<BR>CONTENT_LENGTH : %d\n", atoi(getenv("CONTENT_LENGTH"))); printf ("<BR>DATA : %s\n", data); printf ("</BODY></HTML>\n"); }