Para empezar necesitamos tener un poco
de conocimiento en algún lenguaje de programación(el que sea).
La idea de esta guia es utilizar como base Perl, aunque seran dados ejemplos en C y
tambien en Pascal (vamos Turbo todavia).
Creo que con eso basta para dar una idea general, (que por otra parte es lo que pretendo),
y las adaptaciones necesarias para cualquier otro lenguaje con un poco de ingenio se
podran hacer sin problemas.
Que son los scripts CGI?
Normalmente cuando un browser de Web
llama a una URL en particular, sucede lo siguiente. Primero la computadora contacta el
HTTP server con dicha URL. El server HTTP revisa si el archivo requerido por nuestra
computadora se encuentra en su sistema, en caso afirmativo envia el archivo como
respuesta. Nuestra computadora entonces, muestra el archivo en el formato apropiado.
Ademas de todo esto, los server de Web
están configurados de tal manera que cada vez que se requiere un archivo de un directorio
determinado (usualmente el cgi-bin), dicho archivo no es enviado; sino que es ejecutado
como un programa y la salida de este programa es enviada a nuestra maquina para que esta
la muestre. Esta funcion es conocida como "Common Gateway Interface" y los
programas a los que nos referimos son los llamados scripts CGI.
En esta segunda parte veremos scripts
que funcionan en base a los datos y variables que le son enviados a travez de un FORM en
una pagina HTML, y dejaremos para la tercera de aquellos que no necesitan de esta input,
por ejemplo los counters, las animaciones y otras cosas un poco mas complicadas.
Nuestro primer script.
Para empezar por lo mas simple y poder
apreciar la funcionalidad de este sistema veremos un script muy facil de entender, el cual
no necesita que le sean suministrados datos de ningun tipo para funcionar.
Pero sigamos con lo nuestro:
PERL
!#/usr/bin/perl
<Esta linea llama al interprete de PERL
Es así de facil!! Y lo mejor de todo es que
funciona!
Observen que l io primero que
retornamos es un header indicando de que tipo es la información que enviamos, en este
caso se trata de una pagina HTML, por lo tanto el header apropiado es :
Content-type: text/html
Tomemos en cuenta tambien que los
primeros dos saltos de linea que introducimos son significattivos. Los códigos de retorno
MIME, a los cuales pertenece "Content-type..", necesitan dos
"newlines" siguiendolos para delimitar su fin. No enviar este segundo newline
nos traera bastantes problemas. Los demas "newline" incluidos en la pagina que
generamosno son realmente necesarios, pero facilitaran la lectura de alguien que haga un
"View source".
Como vemos en los ejemplos tuvimos que
generar todos los tags de la pagina, pero eso resulto muy simple, ¿No es asi?.
Ahora vamos a hacer algo un poco mas interesante, vamos a solicitar algunos datos con un
form apropiado, y vamos a retornar una pagina que contenga los nombres de las variables
utilizadas junto con el contenido de cada una ingresado por el usuario.
Un script que hace eco de un
Form
En este punto comenzaremos a hacer uso
de librerias especializadas (los sites donde conseguir cada una de las librerias figuran
al final de este texto).
Quisiera recalcar que estas librerias no son únicas, existen muchas variaciones sobre el
mismo tema, y cada una de ellas tiene su propia forma de manejarse, por lo tanto es
conveniente revisar cuidadosamente la documentación que la acompaña en caso de que se
utilize alguna otra que no figure aqui.
Estas librerias nos ahorraran el
trabajo de separar los distintos componentes que son encapsulados en la variable de
entorno QUERY_STRING (recuerdan lo que mencionamos en la primera parte?).
En el caso que estudiaremos, la llamada la hacemos al script en Perl, pero obviamente
cambiando el nombre del ejecutable de acuerdo al lenguaje que estemos utilizando esto se
soluciona.
Veamos el from que vamos a utilizar:
<html>
<head>
<title>prueba con un form</title>
</head>
<body>
<h1>Ingresa los datos que corresponda para hacer la prueba:</h1>
<br><hr>
<form method="post"
action="http://mimaquina.midominio/cgi-bin/prueba.pl">
<ul>
<li>Nombre: <input type="text" name=nombre size=20>
<li>Edad: <input type="text" name=edad size=2>
<li>Hincha de:
<select name="equipo">
<option selected> Boca juniors
<option>River Plate
<option>San Lorenzo
<option>Independiente
<option>Racing Club
</select>
<li>Email: <input type="text" name=email size=20>
</ul>
<input type="submit" value="ok"><br>
<input type="reset" value="borrar"><br>
</form>
<hr>
</body>
</html>
Ingresa los datos que
corresponda para hacer la prueba:
El script que utilizaremos sera muy
simple y nos va a servir de base para futuros desarrollos. Veamos paso a paso su
estructura:
Primero llama al
interprete en caso de ser necesario (Perl)
Luego de incluir/carga
la libreria, de alguna manera corre la funcion que separa QUERY_STRING en sus
componentes individuales.
asignamos dichos
componentes a las vasriables que vamos a utilizar.
Imprimimos una salida
como en cualquier programa y...
print &PrinHeader;
print"<html>\n";
print"<head>\n";
print"<title>Aprendiendo CGI segundo ejercicio</title>\n";
print"</head>\n";
print"<body>\n";
print"Tu nombre es ",$nombre,"<br>\n";
print"Tienes",$edad," años y sos simpatizante de
",$equipo,"<br>\n";
print"Si alguien quisiera escribirte tu email es.
",$email,"<br>\n";
print"<hr>\n";
print"</body></html>\n";
PASCAL
Uses tpwcgi;
var
nombre,edad,equipo,email:string;
Begin
Start CGI;
nombre:=Getvalue('nombre',1);
edad:= Getvalue('edad',1);
equipo:=Getvalue('equipo',1);
email:=Getvclue('email',1);
Makeheader;
Send ('<html>');
Send('<head>');
Send('<title>Aprendiendo cgi segundo ejercicio</title>');
Send('</head>');
Send('<body>');
Send('<hr>');
Send('tu nombre es'+nombre+'<br>');
Send('tienes'+edad+'años y sos simpatizante de'+equipo+'<br>');
Send('si alguien quisiera escribirte tu email es'+email+'<br>');
Send('<hr>');
Send('</body></html>');
printf ("Content-type:text/html\n\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>Aprendiendo cgi segundo ejercicio</title>\n");
printf("</head>\n");
printf("<body>\n");
printf("<hr>\n");
printf("Tu nombre es %s <br>\n",nombre);
printf ("Teneis %s años y sos simpatizante de %S <br>\n",edad,equipo);
printf("Si alguien quisiera escribirte tu email es %s <br>\n",email);
printf("<hr>\n");
printf("</body></html>\n");
}
Es evidente que a partir de este punto
podriamos abordar cosas mas complicadas si quisieramos, ya que es posible utilizar todos
los recursos de cada lenguaje para efectuar las acciones y procesos que queramos.
Como sugerencia, la estructura que propongo para un script mas o menos decente es la
siguiente ( de todas maneras igual que en matematicas de primer grado, el orden de los
factores no altera el producto, aunque si lo hace mas dificil de mantener)
Asignación de variables
Proceso principal del script que
genera la salida que queremos a partir de los datos de entrada
Envio de la pagina con los datos del
proceso
Lo mejor es comenzar a practicar con
las estructuras más comunes, decision (if) e iteración (for), haciendo pequeños
programas y probando las salidas obtenidas.Por ejemplo, un script que dependiendo del
contenido de la variable "nombre", retorne una pagina con distintos mensajes
segun sea quien ha completado el form.
Los scripts pueden hacer cosas mas complicadas, como verificar que los campos sean
llenados correctamente, modificar archivos y hasta mandar una pagina que no haya sido
elaborada por ello. En el siguiente y ultimo punto veremos como implementar estos metodos
en la forma de un "mini-guestbook".
Un Mini-Guestbook
Vamos a armar una especie de Mini.Libro
de firmas, una aplicación bastante difundida, que nos servira de ejemplo para mostrar los
puntos que mencionamos arriba.
Esto comienza con un form muy chiquito que solicita los siguientes datos:
Nombre
Email
Comentarios
A partir de ahi, lo que el usuario
ingrese sera grabado en otra pagina, la pagina del guestbook mas precisamente, y luego
finalmente se presentara una pantalla agradeciendo el comentario e invitando a mirar el
libro.
Para poder conseguir lo que queremos,
utilizaremos un metodo muy comun, estableceremos una marca invisible (un comentario) en la
pagina en cuestion y tomaremos dicha marca como punto de partida para cada nuevo
comentario. Los pasos a seguir en este caso son los siguientes:
Verificar la entrada del usuario,
para que no existan campos vacios, retornando un mensaje de error si existe algun
problema.
Abrir y leer la pagina del
mini-guestbook linea por linea (grabando cada una de ellas en un archivo temporario) hasta
encontrar la marca que indica el comienzo de los comentarios (o sea el ultimo ingresado),
grabar despues de la misma el input del usuario y terminar de copiar el resto del archivo.
Cerrar los archivos, borrar el
original y renombrar el temporario.
Devolver un codigo de retorno
"Location.." que llevara al usuario a una pagina de agradecimiento que tendra un
link al guestbook.
Muchos se preguntaran, y que pasa si
dos usuarios acceden al mismo tiempo al archivo? Como hacen para leerlo/grabarlo? Quien
tiene prioridad?.
Creo que seria intentar avanzar demasiado en este momento, a manera de comentario (de
todas formas les contare como hacerlo en la tercera parte) lo que se necesita es una
manera de trabar el acceso al archivo mientras se esta trabajando con el.
Como siempre veremos el Form que
permite al usuario agregar su nombre y su comentario en nuestro libro de firmas.
<html>
<head>
<title>Firme nuestro libro</title>
</head>
<body>
<h1>Ingrese sus datos y el comentario que desee hacernos</h1>
<br><hr>
<form method="post"
action="http://mimaquina.midominio/cgi-bin/ingreso.pl">
Nombre:<br><input type="text" name=nombre size=20><br>
Email: <br><input type="text" name=email size=20><br>
Su comentario: <br><textarea name="comentario" rows=5
cols=40>Escriba aqui su comentario</TExtarea><br>
<input type="submit" value="Ok"><br>
<input type="reset" value="borrar"><br>
</form>
<hr>
</body>
</html>
if (($nombre eq
"2)||($emaileq"")||($comentarioeq""))
{
print&PrintHeader;
print"<html>\n";
print"<head>\n";
print"<title>error en el ingreso</title>\n";
print"</head>\n";
print"<body>\n";
print"<hr>\n";
print"<h1> Alguno de los campos que ingreso no contenia datos
</h1>";
print" Por favor apriete este boton para ingresar sus datos nuevamente";
print"<a href="/imagenes/boton.gif">;
printf"<hr>\n";
print"</body></html>\n";
exit;
}
open (GB,"<htdocs/mini-gb.html");
@lineas=<GB>;
close GB;
if ((nombre = '')or (email='')or(comentario=''))
then begin
MakeHeader;
Send ('<html>');
Send('<head>');
Send('<title>Error en el ingreso</title>');
Send('</head>');
Send('<body>');
Send('<hr>');
Send('<h1> Alguno de los campos que ingreso no contenia datos</h1>');
Send('Por favor apriete este boton e ingrese sus datos nuevamente');
Send('<a href="/imagenes/boton.gif">');
Send ('<hr>\n');
Send('</body></html>');
EndCGI;
end;
else begin
Readln(Arch-In, linea);
while and NOT EOF (Arch.In) do
begin
writeln (Arch-Out, linea);
readln(Arch-In, linea);
if (linea = ' <!--ultimo comentario-->')
then begin
writeln (Arch-Out, linea);
linea:= 'Nombre:'+nombre+'<br>;
Writeln (Arch-Out, linea);
linea:=´'Email: <a href="mailto'+email+'">+email'</a><br>';
Writeln (Arch-Out, linea;linea);
linea:= 'Comentario:<br>';
writeln (Arch-Out,linea);
for i:=1 to GetLinNum('comentario') do
begin
linea:= GetValue ('comentario',1)+'<BR>';
Writeln (Arch-Out, linea);
end;
end;
end;
Me parecio redundante incluir la
version en C ya que esta puede ser facilmente incluida a partir del fuente de Pascal.
Como el TEXTAREA que utilizamos para cargar el comentario entrega sus datos solo separados
por newlines, tuvimos que hacer un pequeño proceso en cada uno de los programas para
generar un <br< por cada uno de ellos en la pagina definitiva.
Notaran que existen diferencias en la forma de hacer el "update" del archivo en
cada una de lasversiones. En el fuente Perl aproveche una función de sustitución
bastante potente que simplifica las cosas, en cambio en la version en Pascal hubo
que hacer dicha sustitucion "a mano".
Para finalizar esta segunda parte veremos una lista de cosas a tomar en cuenta la hora de
programar scripts CGI.
Puntos importantes al programar
scripts
Un script debe:
Ser ejecutable (o en el caso de Perl
incluir la llamada al interprete)
Estar ubicado en el directorio
cgi-bin. La ubicación de este server va a estar definida por el administrador del server.
Sea capaz de acceder a los archivos
ue necesita. Como el script corre desde el directorio cgi-bin, todas las
referenciasrelativas que hagamos van a estar referenciadas al mismo. Por las dudas cuando
tengamos que retornar una pagina HTML completa, usemos su URL completa.
Teenr seteados los permisos
correctamente. Perdonen que siga jodiendo con lo mismo, pero más de una vez las cossas no
me anduvieros por esta sencilla razón. (Nadie podia ejecutar el programa excepto yo...)
Bueno, los dejo, espero no haberlos
aburrido demasiado, que les sea de utilidad y encontrarlos leyendo la tercera y ultima
parte (espero que en el tiempo que tarde en terminarla no surjan demasiadas cosas nuevas
que me hagan empezar una cuarta ;-P!).