Site hosted by Angelfire.com: Build your free website today!
Programación con CGI's
Qué es un CGI 


El Common Gateway Interfase(CGI) 

[1], actualmente en su versión 1.1, es un estándar para programas que sirven de puente entre el Web y una aplicación [2].

Por ejemplo, uno puede querer que su aplicación, por lo general de base de datos, pueda utilizarse a través de páginas del Web. Así, se puede hacer que un programa CGI pinte una interfaz para el usuario ( forma del Web) quien llena esta solicitud completando ciertos campos de texto o seleccionando opciones de menús. Esta solicitud es recogida por el CGI quien la transforma en comandos y datos inteligibles por la aplicación, a su vez ésta le regresa al CGI los resultados de la consulta y el CGI se los despliega al usuario en una nueva página Web, tal como se muestra en la figura 1.

Figura 1.CGI como interfaz entre el Web y la aplicación

Así, un programa que siga el estándar CGI (llamémoslo simplemente CGI), está escrito en algún lenguaje de programación interpretado o compilado como pueden ser C, Perl o scripts de Unix y que manda a ejecutar una aplicación y despliega sus resultados en forma de páginas del Web, esto es, hipertexto HTML [3]. También un CGI puede ejecutar otros CGIs y(o) una o varias aplicaciones, o puede ser por sí mismo una aplicación simple, con tal de que cumple con el estándar.


Qué se puede hacer y qué no se puede hacer con un CGI 


El estándar CGI surgió al mismo tiempo que el Web, para ampliar sus posibilidades al incluirle programación. Un CGI siempre corre del lado del servidor, lo que significa que cuando se accede a una página Web que contiene un CGI, éste se ejecuta automáticamente en el servidor y lo que se ve posteriormente en una página, es el resultado de esta ejecución. Esto redunda en lo siguiente:


Aumento de la carga en el servidor, si se ejecutan simultáneamente varios CGIs complejos o que usen aplicaciones complejas. 
· Por lo anterior, el cliente no se sufre sobrecarga y, de hecho, el usuario puede no darse cuenta de que la página que está viendo ha sido generada por un CGI (y no proviene de un archivo HTML). 
· Si no se toman las debidas (y razonables) precauciones al crearlo, un CGI puede, en un momento dado, comprometer la seguridad del servidor, puesto que dentro de un CGI se puede ejecutar cualquier programa o desplegar cualquier archivo que se encuentre en dicho servidor [4]. A pesar de lo anterior, siempre se puede deshabilitar la ejecución de CGIs (comportamiento preestablecido --default) y habilitar sólo ciertos directorios como mecansmo de protección. El cliente no resulta afectado en este sentido. 
· Un CGI tiene a su disposición cierta información proveniente del cliente y a través de variables de ambiente se puede conocer, por ejemplo, la dirección IP y el tipo de cliente y, cuando tanto en el cliente como en el servidor se disponen de los recursos adecuados, se puede conocer el usuario de la página actual y más información, aunque esto no está disponible en el comportamiento normal, ni en todos los servidores y mucho menos en los clientes (aunque esta situación puede cambiar en el futuro). 
· Puede hacer todo lo que un programa en el servidor sea capaz de hacer, con tal de que su salida sea HTML. Por ejemplo, puede generar archivos de texto, gráficos o sonido, acceder a bases de datos, llamar a otros CGIs o HTMLs y mezclar todo ésto. 
· Al igual que casi todo en el Web, los CGIs no pueden funcionar síncronamente con el usuario, pues tienen que esperar a que el cliente los mande a ejecutar. Por ejemplo, los programa del tipo me preguntas - te respondo( query) son ideales para ser ejecutados por medio de CGIs, sin embargo, aplicaciones más interactivas como editores de texto o graficadores, no correrían o de hacerlo sería en forma mediocre (por ejemplo, ¡tener que presionar un botón con el mouse luego de cada línea en un editor!). Algo similar ocurre con aplicaciones que necesiten estar variando porciones de una misma pantalla Web, ya sea continuamente o luego de la ocurrencia de un evento. 
Por supuesto, un CGI se puede combinar con otros recursos del Web, como recarga dinámica, formas, mapas sensitivos, "server includes", applets de Java, etc. 



Aplicaciones de CGIs 


Los CGIs se aplican frecuentemente en " search engines ", es decir, en combinación con programas de acceso a bases de datos (del tipo Yahoo[5]). Como intérprete de formas de recolección de información, donde el CGI recibe la información proporcionada por el usuario, la selecciona y realiza alguna acción con ella, desde almacenarla hasta deducir algún hecho de ella. Los CGIs también se emplean en robots[6], los cuales son programas que "simulan alguna acción humana", en este caso, de interacción con el Web, como puede ser el localizar alguna información de manera autónoma, conectándose a diversas páginas o copiando páginas enteras de servidores a nuestra máquina o quizás, traduciendo y dándole formato a un "e-mail" común y corriente o texto ASCII o documento en algún otro formato, pasándolo al formato HTML e instalándolo automáticamente en el servidor. Hay CGIs que sirven de interfaz con procesadores de imágenes y que están disponibles en el Web de forma gratuita; otros más sirven de interfaz con programas científicos [7].

Para que un programa común y corriente se convierta en CGI tiene que generar como resultado (por la salida estándar) un documento HTML y debe cumplir con los lineamientos del estándar MIME [8] para especificar qué tipo de documento se generará, comúnmente text/html. Para ejemplificar, y seguiendo la tradición, a continuación se presenta un CGI escrito en script Unix, que imprime una conocida frase:


echo "Content-type: text/html"
echo ""
echo "<H1>Hola mundo!</H1>"


Las dos primeras líneas, debidas al estándar MIME (no aparecerán en la página Web pero hay que ponerlas), dicen que lo que a continuación viene es un texto de tipo html. En la tercera línea se pueden observar las etiquetas ( tags) de HTML para ajustar el tipo de texto (letras grandes). A continuación viene la versión C del mismo CGI:


main(){
printf("Content-type: text/html\n\n");
printf("<H1>Hola mundo!</H1>");
}


En vez de Content-type puede ir Location: http://.., en cuyo caso el CGI no generará una página nueva, si no que llamará a una ya existente. Cualquiera que sea el caso, la siguiente línea debe estar en blanco.

Como ya se ha dicho, un CGI dispone de ciertas variables de ambiente(el PATH actual, por ejemplo), la más importante es QUERY_STRING que, cuando se utiliza con formas Web con el método GET, registra los datos introducidos en la forma. Si e usa el método POST, estos datos se le pasan al CGI (la acción, en este caso) por la entrada estándar, capturable en C por ejemplo, con scanf, y el número de caracteres enviados se registra en la variable CONTENT_LENGTH.

Supongamos que se tiene una "aplicación" que solicita se intruduzca la letra T (seguida de Enter) y luego "se alegra" si el usuario colaboró o "se enoja" en caso contrario. Con el fin de que se pueda probar, se expondrá el código fuente en C de esta "aplicación", aunque como se puede notar, no siempre se dispondrá de dicho código fuente, como por ejemplo una aplicación de base de datos o un cálculo matemático complejo que genere un archivo GIF para su visualización:


void main(){
char l;
printf("Dame una \"T\" por favor: ");
scanf("%c", &l);
if(l=='T') printf("Gracias por colaborar!\n");
else printf("Usuario mezquino!\n");
}


Compílelo y observe cómo se ejecuta.

Ahora se procede a crearle su interfaz con el Web, es decir, se escribirá un CGI (las líneas que c ienzan con "#" son comentarios):


#!/bin/csh
# Script en c-shell
# Si la variable QUERY_STRING existe y no está vacía,
# se entiende que ya se ha corrido antes este programa
# y que dicha cadena contiene lo que el usuario seleccionó
# de lo contrario, pinta una forma y pide al usuario
# que seleccione algo.
if ($?QUERY_STRING && $QUERY_STRING != "") then
setenv LETRA `echo $QUERY_STRING | sed 's/letra=//'` 
# A continuación desplegaremos una nueva página conteniendo
# lo que nos devuelva Test1 quitándole la cadena que ya se 
# imprimió en la primera ejecución de este programa, esta 
# se le quita con el "sed" del 4o echo. Notar que hay que 
# cumplir con la norma MIME como todo CGI (echos 1o y #2o) 
echo Content-type: text/html 
echo 
echo "<H2>" 
echo `echo $LETRA | /usr/people/gmv/CCC/Test1 | sed 's/Type the letter T and press Enter: //'`
echo "</H2>" setenv QUERY_STRING echo "<a href=/gmv-bin/interface.cgi>BACK</a>" 
else 
# Si no hay QUERY_STRING, significa que se está corriendo # por primera vez, entonces despliega la interface web. 
# Content... le dice que lo que viene es un #texto de tipo
# html (para cumplir con la norma MIME de todo CGI) luego
# de esa linea DEBE ir una linea en blanco. El "cat" manda
# a imprimir lo que le sigue y hasta #encontrar "EOF"
cat <<EOF 
Content-type: text/html

<HTML>
<HEAD><TITLE>Interface para Test1</TITLE></HEAD> 
<BODY> <FORM METHOD="GET" ACTION="/gmv-bin/interface.cgi"> 
<H1>Type the letter T and press Enter: 
<SELECT NAME="letra"> 
<OPTION> A 
<OPTION> S
<OPTION> T
<OPTION> Q 
<OPTION SELECTED> t 
</SELECT> 
</H1> <p>
<CENTER><INPUT TYPE="Submit" VALUE="OK"></CENTER> </FORM> </BODY> </HTML>
EOF
endif
# ------ fin del CGI ------


Se puede simplificar el CGI si se crean por separado los archivos HTML que contienen las páginas de pregunta y de respuestas y el CGI únicamente los llamaría.

Por otra parte, como se dispone del programa fuente en C, éste se puede modificar para incuirle los estándares de MIME para C s, así una versión en C muy simple del CGI anterior puede ser la siguiente:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
char l,*query;
int cl;
if(!(query=getenv("QUERY_STRING")) || (strlen(query)==0)){
/* no ha habido query */
puts("Content-type: text/html\n");
puts("<HTML>");
puts("<HEAD><TITLE>Interface para Test</TITLE></HEAD>");
puts("<BODY><FORM METHOD=\"GET\" ACTION=\"/fhca-bin/test.cgi\">");
puts("<H1>Dame una \"T\" por favor: ");
puts("<SELECT NAME=\"letra\">");
puts("<OPTION> A");
puts("<OPTION> S");
puts("<OPTION> T");
puts("<OPTION> Q");
puts("<OPTION SELECTED> t");
puts("</SELECT>");
puts("</H1> <p>");
puts("<CENTER><INPUT TYPE=\"Submit\" VALUE=\"OK\"></CENTER>");
puts("</FORM> </BODY> </HTML>");

else {
cl=strlen(query);
puts("Content-type: text/html\n\n<H1>");
if (query[cl-1]=='T') { /*la respuesta es el último caracter*/
puts("Gracias por c aborar!");
puts("</H1>\n");
}
else
puts("Usuario mezquino!</H1>\n");
puts("<a href=/fhca-bin/test.cgi>BACK</a>");
}
}



A manera de conclusión


¿La muerte de un estándar? Comparación con Java 

Los CGIs han existido desde el principio del HTML y a mi parecer permanecerán entre nosotros todavía un tiempo más por dos razones: Facilidad de uso y porque se ejecutan en el servidor.

El lenguaje Java, con mucho auge actualmente, desde cierto punto de vista se puede ver como un fuerte competidor de los CGIs y muchos ya lo toman como sustituto, aunque trataré de mostrar que se trata de dos herramientas diferentes o dos puntos de vista para resolver el mismo problema: programar en el Web.

Primero que nada, Java es un lenguaje de programación con todas las ventajas que esto implica, incluyendo manejo sencillo de gráficos, y cada vez que se accede a un applet, éste se carga en el cliente y es allí donde se corre; esto es, aprovecha todos los recursos y tiene todas l limitaciones del cliente (actualmente esto último se vuelve cada vez más irrelevante), además, la parte "complicada" que significa el programar, se salva cada vez mejor con porciones de código ( bibliotecas de applets) ya disponibles. Por otra parte, CGI es un estándar, es decir, una forma de trabajar y no un lenguaje específico; hay que usar un lenguaje externo para crear el programa que cumpla con dicho estándar. Este programa siempre residirá y correrá del lado del servidor, usando sus recursos y observando también sus limitaciones. La diferencia entre ambas herramientas es similar a la observada entre modelos centralizados y modelos distribuidos de comunicación, es por ello que siempre que se desee mantener una aplicación o datos en una sola máquina se preferirá el CGI, mientras que cuando esto no sea importante, se puede preferir la distribución del software con Java.

Los CGIs surgen como necesidad de programar para el Web y específicamente para crear puentes o interfaces a programas disponibles en una sola máquina, centralizando la información y el software que la maneje. Los programas Java que quieran servir para este propósito, necesitan dividirse en dos, una parte en el servidor y la otra en el cliente. La parte en el servidor sirve de verdadero puente de la aplicación con el Web; y la que está en el cliente, sirve de puente entre el Web y el usuario. Esto se puede hacer, gracias a que es incidental (o intencional) que un programa Java corra en conjunción con el Web (pues originalmente se diseño ara funcionar como cualquier otro lenguaje independiente).



Por supuesto, un programa en Java puede servir para muchas más cosas que como puente, puede ser una aplicación por sí mismo al igual que con los CGIs, pero sin las restricciones de dicho estándar y por supuesto, sus características no dependen (ni necesitan) del estándar HTML. Por como surge y por todo el apoyo que ha tenido de parte de las empresas, puede hacer todo lo que el cliente le permita desde la primera versión liberada, y esto es suficiente para la mayoría de los propósitos generales y muchos de los específicos. Por su parte, los CGIs están restringidos a seguir los caminos ya existentes del estándar HTML y sólo pueden crecer en la medida que crezca dicho estándar. En este sentido, una competencia sería muy desleal.

Como conclusión, se puede observar que los CGIs sirven muy bien para el propósito específico de funcionar como puentes para aplicaciones ya existentes y, además, son muy simples. Los programas Java pueden, en un momento dado, servir para dicho propósito pero además tienen muchas otras ventajas y un crecimiento mucho más claro y veloz, tomando como punto de comparación el que con ambos se puede programar en el Web.

atras