Contenido dinámico con CGI


Contenido dinámico con CGI

Módulos relacionados

mod_alias
mod_cgi
Directivas relacionadas

AddHandler
Options
ScriptAlias

CGI (Common Gateway Interface) define una manera de que un servidor Web interactúe con programas externos generadores de contenido, los cuales son a menudo denominados programas CGI o CGI scripts. Este es el modo más común y simple de crear contenido dinámico en tu sitio Web. Este documento será una introducción para configurar CGI sobre tu servidor web Apache, y los primeros pasos para escribir programas CGI.


Configurando Apache para permitir CGI

Para conseguir que tus programas CGI funcionen apropiadamente, necesitas tener Apache configurado para permitir ejecución CGI. Hay bastantes formas de hacer esto.

ScriptAlias

La directiva ScriptAlias le dice a Apache que un directorio concreto es asignado para programas CGI. Apache asumirá que cada fichero de este directorio es un programa CGI, e intentará ejecutarlo, cuando este recurso particular sea solicitado por un cliente.

La directiva ScriptAlias se muestra así:

        ScriptAlias /cgi-bin/ /usr/local/apache/cgi-bin/

El ejemplo pertenece a tu fichero de configuración por defecto httpd.conf, si es que has instalado Apache en la ruta por defecto. La directiva ScriptAlias es más agradable que la directiva Alias, que define un prefijo URL que se mapea a un directorio particular. Alias y ScriptAlias son usados normalmente para directorios que están fuera del directorio DocumentRoot. La diferencia entre Alias y ScriptAlias es que ScriptAlias tiene el significado adicional de que todo bajo el prefijo URL se considera un programa CGI. Así pues,, el ejemplo anterior le dice a Apache que cualquier solicitud de un un recurso que comienza con /cgi-bin/ deberá servirse desde el directorio usr/local/apache/cgi-bin/, y debiera tratarse como un programa and should be treated as a CGI.

Por ejemplo, si la URL http://dev.rcbowen.com/cgi-bin/test.pl es solicitada, Apache intentará ejecutar el fichero /usr/local/apache/cgi-bin/test.pl y devolver la salida. Por supuesto el fichero tendrá que existir, y ser ejecutable, y devolver la salida de una manera concreta, o Apache devolverá un mensaje de error.

CGI fuera de los directorios ScriptAlias 

Los programas CGI son restringidos a menudo a los directorios ScriptAlias por razones de seguridad. De este modo, los Administradores pueden controlar estrictamente a quien se permite usar programas CGI. Sin embargo, si las precauciones de seguridad apropiadas, no hay razón por la que los programas CGI no puedan ser ejecutados desde directorios arbitrarios. Por ejemplo, puedes querer permitir a los usuarios tener contenido web en sus directorios con la directiva UserDir. Si ellos quieren tener sus propios programas CGI, pero no tienen acceso al directorio principal cgi-bin, necesitarán ejecutar los programas CGI desde alguna parte.

Usando explícitamente opciones que permiten ejecución CGI

Podrías usar explícitamente la directiva Options, dentro de un fichero de configuración principal del servidor, para especificar que la ejecución CGI esta permitida en un directorio concreto:

        <Directory /usr/local/apache/htdocs/directoriocualquiera>
                Options +ExecCGI
        </Directory>

La directiva anterior le dice a Apache que permita la ejecución de ficheros CGI. Necesitarás a su vez decirle al servidor que ficheros son CGI. La directiva AddHandler le dice al servidor que trate todos los ficheros con extensión cgi o pl como programas CGI:

     AddHandler cgi-script cgi pl

Ficheros .htaccess

Un fichero .htaccess es un modo de establecer directivas de configuración basadas en un directorio. Cuando Apache sirve un recurso, mira en el directorio del cual esta sirviendo, un fichero llamado .htaccess, y, si lo encuentra, aplicará las directivas que encuentre en el. Los ficheros .htaccess pueden estar permitidos a través de la directiva AllowOverride, que especifica que tipos de directivas pueden aparecer en ellos, o si no están permitidos en ningún caso. Para permitir la directiva que necesitamos en este caso, será necesaria la siguiente configuración en tu servidor principal.:

        AllowOverride Options

En el fichero .htaccess, necesitarás la directiva:

        Options +ExecCGI

la cual informa a Apache que la ejecución de programas CGI está permitida en este directorio.


Escribiendo un programa CGI

Hay 2 diferencias principales entre programación ``regular'' y programación CGI.

Primero, toda la salida de tu programa CGI debe estar precedida por una cabecera tipo-MIME. Esta es una cabecera HTTP que le dice al cliente que orden está recibiendo de sus contenidos. La mayoría de las veces, esto sería algo asi:

        Content-type: text/html

Segundo, tu salida necesita estar en HTML, o algún otro formato que un navegador pueda ser capaz de visualizar. Normalmente, será HTML, pero en ocasiones puedes querer escribir un programa CGI que genere una imagen gif, u otro contenido que no fuera HTML..

Aparte de estas dos consideraciones, escribir un programa CGI, es muy parecido a escribir cualquier otro programa.

Tu primer programa CGI

Lo siguiente es un ejemplo de un programa CGI que imprime una línea en tu navegador. Teclea lo siguiente, y sálvalo en un fichero llamado first.pl, dentro de tu directorio cgi-bin.

        #!/usr/bin/perl
        print "Content-type: text/html\r\n\r\n";
        print "Hello, World.";

Incluso si no estás familiarizado con Perl, deberías comprender al verlo, lo que realiza el programa. La primera línea le dice a Apache (o cualquiera de los interpretes de comandos sobre cual se ejecute) que este programa puede ser ejecutado inyectando el fichero al interprete que podemos encontrar en la ruta /usr/bin/perl. La segunda línea imprime la declaración del tipo de contenido del cual hemos hablado, seguida de dos retornos de carro emparejados al carácter de nueva línea. Esto coloca una línea en blanco tras la cabecera, que indica el final de las cabeceras HTTP, y el principio del cuerpo. La tercera línea imprime la cadena ``Hello, World.'' Y ese es el final.

Si abres tu navegador favorito y le dices que cargue la dirección

        http://www.example.com/cgi-bin/first.pl

o en el sitio donde tu salves tu fichero, verás en la primera línea Hello, World. aparecer en la ventana de tu navegador. No es muy excitante, pero ya lo tienes funcionando, y yá tendrás oportunidad de que funcione todo lo que quieras.


Pero todavía no funciona!

Hay 4 cosas básicas que puedes ver en tu navegador cuando intentes acceder a tu programa CGI desde la web:

La salida de tu programa CGI
Cojonudo! Eso significa que todo funciona bien.

El código fuente de tu programa o un mensaje "POST Method Not Allowed"
Significa que no tienes Apache correctamente configurado para procesar tu programa CGI. Reléete la sección configurando Apache e intenta encontrar el fallo.

Un mensaje que empieza con "Forbidden"
Quiere decir que hay un problema de permisos. Chequea los Logs de error de Apache y la sección siguiente: permisos de ficheros.

Un mensaje diciendo: "Internal Server Error"
Si compruebas los Logs de error de Apache, probablemente hallarás algo que diga "Premature end of script headers", posiblemente junto a un mensaje de error generado por tu programa CGI. En este caso, querrás comprobar las secciones siguientes para ver que puede estar impidiendo a tu programa CGI de emitir las cabeceras HTTP apropiadas.

Permisos de fichero

Recuerda que el servidor no los ejecuta como tu. Es decir, cuando un servidor arranca, esta ejecutando con permisos de un usuario sin privilegios, normalmente ``nobody'', o ``www'' - y necesitará pues permisos extra para ejecutar ficheros cuyo dueño seas tu. Lo normal, es que el modo de asignar permisos suficientes para que un fichero sea ejecutado por ``nobody'' es dar a todos permisos de ejecución sobre ese fichero:

        chmod a+x first.pl

Además, si tu programa lee de, o escribe a, otros ficheros, estos necesitan tener los permisos correctos para permitir esto.

La excepción a esto es cuando el servidor es configurado para usar suexec. Este programa permite a los programas CGI ejecutarse bajo diferentes permisos de usuario, dependiendo de que puesto virtual o directorio propiedad de usuario estén localizados. Suexec tiene un chequeo estricto de permisos, y cualquier fallo en este chequeo resultara ser un fallo del tipo "Internal Server Error" en tus programas CGI. En este caso, necesitarás chequear el fichero log de suexec para ver que chequeo específico de seguridad está fallando.

Información de rutas

Cuando ejecutas un programa desde tu línea de comando, tienes cierta información que es pasado al interprete de comandos sin que te dés cuenta. Por ejemplo, tienes un camino (Nota de traducción: variable informativa sobre los posibles directorios de búsqueda de programas y archivos), el cual dice al interprete donde puede buscar los ficheros a los que referencias.

Cuando un programa ejecuta un programa CGI a través del servidor Web, no tiene ese camino. Cualquier programa que invoques en tu CGI (como por ejemplo: 'sendmail') necesitará ser especificado con su ruta completa, para que el interprete de comandos pueda encontrarlos cuando intente ejecutar tu programa CGI.

Una manifestación común de ello es el camino al interprete del script (a menudo, perl) indicado en la primera línea de tu programa CGI, que buscará algo como:

     #!/usr/bin/perl

Asegúrate que esta es realmente la ruta al interprete.

 

Errores de sintaxis

La mayoría de las veces que falla un programa CGI, es por un problema del propio programa. Es un hecho particularmente cierto cuando provocas el colgado de tu CGI, y solo recibes dos errores. Intenta siempre ejecutar tu programa desde la línea de comando primero, y después pruébalo vía navegador. Esto eliminará gran parte de tus problemas.

Logs de error

Los logs de error son tus amigos. Todo lo malo que ocurre genera un mensaje en el archivo log de errores. Deberías siempre mirar allí primero. Si el lugar donde tu albergas tu sitio web no te permite acceder al log de error, deberías probablemente albergar tu sitio en algún otro sitio. Aprende a leer los logs de error, y encontrarás que casi todos tus problemas son rápidamente identificados, y resueltos.


¿Que ocurre entre bastidores?

Cuando profundices en la programación CGI, te será más útil entender que ocurre entre bastidores. Especialmente, como navegador y servidor se comunican. Porque aunque esta muy bien escribir un programa que imprima ``Hello, World.'', no es especialmente útil.

Variables de entorno

Las variables de entorno son valores que existen siempre que utilizas un ordenador. Son cosas útiles como tu camino (donde el ordenador busca un fichero que implemente el comando que tu tecleas), tu nombre de usuario, tipo de terminal, y demás. Para una lista completa de variables diarias de trabajo, teclea env en tu línea de comando.

Durante la transacción CGI, el servidor y el navegador establecen así mismo variables de entorno, para que puedan comunicarse el uno con el otro. Cosas como tipo de navegador (Netscape, IE, Lynx), tipo de servidor (Apache, IIS, WebSite), nombre del programa CGI que está siendo ejecutado, y demás.

Estas variables están disponibles para el programador CGI, y son media historia en lo que respecta a la comunicación cliente-servidor. La lista completa de variables disponibles está en http://hoohoo.ncsa.uiuc.edu/cgi/env.html.

Este sencillo CGI en Perl, mostrará todas las variables de entorno que le son pasadas. Dos programas similares están incluidos en el directorio cgi-bin de la distribución de Apache. Ten en cuenta que algunas son necesarias, mientras que otras son solo opcionales, así que puedes ver algunas listadas no estén en la lista oficial. En cualquier caso, Apache provee muchas formas diferentes de añadir tus propias variables de entorno a las provistas por defecto.

     #!/usr/bin/perl
     print "Content-type: text/html\n\n";
     foreach $key (keys %ENV) {
          print "$key --> $ENV{$key}<br>";
     }

Entrada estándar y Salida estándar

Otra comunicación entre el servidor y el cliente tiene lugar sobre la entrada estándar (STDIN) y la salida estándar (STDOUT). En un contexto normal del día a día, STDIN viene a ser el teclado, o un fichero sobre el cual actua un programa, y STDOUT significa normalmente la consola o pantalla.

Cuando colocas un formulario web en un programa CGI, los datos de este formulario se empaquetan en un formato especial y se entregan a tu programa CGI sobre STDIN. El programa puede entonces procesarlos aunque fueran introducidos a través de teclado, o de un fichero.

El ``formato especial'' es muy simple. Un nombre de campo y su valor son asociados conjuntamente con un signo igual (=), y los pares de valores son asociados con un ampersand (&). Los caracteres problemáticos como espacios, ampersands, y signos igual, son convertidos a su valor hexadecimal para que no estorbe nuestro trabajo. El total de las cadenas de datos vendría a ser algo como:

     name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey

Verás algunas veces este tipo de cadena añadidos a una URL. Cuando se hace esto, el servidor pone esta cadena en una variable de entorno llamada QUERY_STRING. A esto se le denomina una solicitud GET. Tu formulario HTML especifica si se utiliza un GET o un POST para entregar los datos, estableciendo el atributo METHOD en la etiqueta FORM.

Tu programa es entonces el responsable de desglosar la cadena en información útil. Afortunadamente, hay librerías y módulos disponibles para ayudarte a procesar estos datos, así como a manipular otros aspectos de tu programa CGI.


Librerías/módulos CGI

Cuando escribes programas CGI, deberías considerar usar una librería de código, o módulo, para hacer la mayoría del trabajo sucio por ti. Esto conlleva unos pocos errores, y un desarrollo más rápido.

Si escribes programas CGI en Perl, los módulos están disponibles en CPAN. El módulo más popular para este propósito es CGI.pm. Quizás consideres también CGI:Lite, que implementa una funcionalidad mínima, necesaria para la mayoría de los programas.

Si escribes programas CGI en C, hay variedad de opciones. Una de ellas es la librería CGIC, de http://www.boutell.com/cgic/.


Para más información

Hay un gran numero de recursos CGI en la red. Puedes comentar problemas de CGI con otros usuarios en el foro de Usenet: comp.infosystems.www.authoring.cgi. Y la lista de distribución -servers de HTML Writers Guild es un gran recurso de respuestas a tus cuestiones. Puedes encontrar más en http://www.hwg.org/lists/hwg-servers/.

Y, por supuesto, debieras probablemente leerte las especificaciones CGI, las cuales tienen todos los detalles sobre operatividad de programas CGI. Puedes hallar la versión original en la NCSA y encontrarás un borrador actualizado del Proyecto Common Gateway Interface RFC.

Cuando envíes una pregunta sobre un problema en un CGI que estés teniendo, ya sea una lista de distribución o un foro Usenet, asegúrate de suministrar información suficiente acerca de lo que ocurra, lo que esperabas que ocurriría, y que diferencias con respecto a lo que ocurre actualmente, que servidor estás utilizando, que lenguaje, y si es posible, el código. Esto facilitará la resolución de tu problema.

Ten en cuenta que las preguntas sobre problemas con CGI no deben ser nunca enviadas a la base de datos de errores de Apache a menos que estés seguro que has encontrado un problema en el código fuente de Apache.