Introduction - Les paramètres - Redirection - Les Images - protection par mot de passe - Les cookies - Base de données - FAQ

Programmes CGI avec Delphi et Kylix - Passage de paramètres


GET et POST

Il existe (au moins ?) deux méthodes pour passer des paramètres à un programme CGI.
  • <form method=GET action="program.exe">
  • <form method=POST action="program.exe">
Pour déterminer la méthode employée, il suffit dans votre programme de regarder la variable d'environnement REQUEST_METHOD
J'en profile pour vous présenter la fonction que j'utilise pour les lire les variables d'environnement:
function getvar(varname:string):string;
{$IFDEF LINUX}
 begin
  result:=getenv(PChar(varname));
 end;

{$ELSE}
 var
  buffer:array[0..1024] of char;
  size:integer;
 begin
  size:=GetEnvironmentVariable(PChar(varname),buffer,sizeof(buffer));
  if size=0 then getvar:='' else getvar:=String(buffer);
 end;

{$ENDIF}
Mais c'est juste parceque je préfère travailler avec des String...

Sous DOS (en .BAT) ça donne :
@ECHO OFF
ECHO content-type: text/html
ECHO.
ECHO ^<HTML^>^<HEAD^>^<TITLE^>^</TITLE^>^</HEAD^>^<BODY^>

ECHO REQUEST_METHOD=%REQUEST_METHOD%
ECHO ^</BODY^>^</HTML^>
Notez l'utilisation du "^" pour devant les symbols réservés du DOS (< > & ...)

Donc, on commence par faire un GetVar('REQUEST_METHOD') qui renvoie 'GET' ou 'POST'

Selon la norme CGI, les paramètres sont alors lu :
  • Dans la variable QUERY_STRING pour la méthode GET
  • Dans l'entrée standard (ReadLn) pour la méthode POST
La méthode POST est en fait utilisée quand le nombre de paramètres est trop important, ce qui ne veux pas dire grand chose, mais qui peux se comprendre...n'oublions pas que la méthode GET utilise une variable d'environnement pour tous les paramètres...

QUERY_STRING

La variable QUERY_STRING contient donc la liste de paramètres sous une forme qui ne vous est sûrement pas inconnue... mais d'abord le code HTML :
<form method="GET" action="program.exe">
<input type=text name="toto" value="titi">
<input type=submit value="GO">
</form>
ce qui donne :
en cliquant sur "GO" (pas ici, ça marchera pas !) le programme "program.exe" est appelé sous la forme : http://www.server.fr/cgi-bin/program.exe?toto=titi

Et c'est ce qui suit le "?" qu'on retrouvera dans QUERY_STRING...Notez que rien n'empêche d'indiquer les paramètres dans un lien "HREF=".
Dernière précision, si la requête possède plusieurs paramètres ils sont séparés par des &; de plus certains caractères sont codés en hexa (comme le "&" par exemple) sous la form %hh, où "hh" est la valeur hexadécimale du code caractère. Ansi "&" sera codé par "%26".

je disais plus haut que vous aviez sans doute déjà vu ce genre de chose :
sur yahoo.com, recherchez "cgi + francais", l'URL apparait alors sous la forme:
http://search.yahoo.com/bin/search?p=cgi+%2B+fran%E7ais
Vous appelez donc le programe "search" avec une variable "p" égale à "cgi + français" (où les espaces sont remplacés par des "+", le "+" par "%2B" et le "ç" par "%E7")

La Méthode POST:

Personnellement, j'ai pas réussit à faire fonctionner cette méthode...

Nouveau ! En fait les données de la méthode POST sont à lire dans l'entrée standard. Pour savoir la taille des données, lire la variable CONTENT_LENGTH.
Ce qui se traduit par :
 // get parm string
  if getvar('REQUEST_METHOD')='POST' then begin
   parmstring:=getvar('CONTENT_LENGTH');
   if parmstring<>'' then begin

    size:=strtoint(parmstring);
    setlength(parmstring,size);
    for i:=1 to size do read(parmstring[i]);
   end;
  end else
   parmstring:=getvar('QUERY_STRING'); 

je vous propose donc ce petit programme cgi, qui permet tout simplement d'afficher ce qui se passe sur le serveur :
program log;

{$apptype console}

// je vous laisse l'adapter pour Linux :)

uses
  windows, sysutils;

var

 i:integer;
 s:string;
 p:pchar;

 flog:textfile;

begin
 assignfile(flog,'c:\temp\log.txt');
 rewrite(flog);

 WriteLn('Content-Type: text/html');
 WriteLn('');

 WriteLn('<html><head><title>Dump CGI</title></head><body>');
 WriteLn('<h1>Dump CGI:</h1>');
 WriteLn('<a href=#Parms>Paramètres du programme</a><br>');
 WriteLn('<a href=#Query>Paramètres CGI</a><br>');
 WriteLn('<a href=#Env>Variables d''environnement</a><br>');
 WriteLn('<a href=#Info>Plus d''info</a><br>');
 WriteLn('<hr>');

 WriteLn('<a name=Parms><h2>ParamCount=',IntToStr(ParamCount),'</h2><ul>');
 WriteLn(fLog,'ParamCount=',IntToStr(ParamCount));

  for i:=0 to ParamCount do begin

   WriteLn('<li>',ParamStr(i));
   WriteLn(fLog,'-',ParamStr(i));
  end;

 // fichier en entrée
 WriteLn(fLog,'Input :');
 WriteLn('<h2>StdInput:</h2><ul>');
 if Not Eof(Input) then begin

  Read(Input,s);
  WriteLn('<li>',s);
  WriteLn(fLog,s);
 end;

 Writeln(fLog,'QUERY_STRING=',ParmString);

 WriteLn('<a name=Env><h2>Variables d''environnement :</h2><ul>');
 p:=GetEnvironmentStrings;
 while StrLen(p)<>0 do begin

  WriteLn('<li>',p);
  WriteLn(fLog,':',p);
  p:=strend(p);
  inc(p);
 end;
 WriteLn('</ul><hr>');

 WriteLn('<a name=Info><a href="http://www.multimania.com/tothpaul">');
 WriteLn('plus d''info sur le CGI</a>');
 WriteLn('</body></html>');


end.
Remarque: j'utilise un fichier log en parallèle pour les cas où la requête n'abouti pas.