Sólo Programadores Banner 468x60
Este mes en Sólo Programadores
Contenido del CD-ROM
Índice temático
Suscripción

Programación de sockets.

Integración del CGI en el servidor web (III)

Si nuestra meta es ampliar el diálogo con un servidor web, de forma que consigamos que el cliente pueda además de recibir información, enviar datos al servidor, tendremos que incorporarle una interfaz con aplicaciones residentes que amplíen su funcionalidad.A lo largo de este artículo iremos viendo la especificación CGI.

INTRODUCCIÓN

En los dos artículos anteriores hemos creado un servidor web que cumplía con la función básica de un servidor de esta clase: servir páginas web (HTML). Sin embargo, el servidor está algo incompleto, ya que no permite a los navegadores (clientes web) que le envíen datos de consultas personalizadas o datos de actualización. Para conseguir que el cliente envíe datos al servidor, debemos dar soporte al comando POST y generar el código necesario para ejecutar la aplicación de servidor cuyo nombre acompaña a la petición.

Las aplicaciones que nuestro servidor será capaz de ejecutar y con las que podrá establecer un diálogo, serán programas CGI (también conocidos como "secuencias CGI" por su implementación en lenguajes de scripts en las máquinas UNIX). En concreto, seguirán la especificación WinCGI que establece los mecanismos para proveer CGI sobre máquinas Windows.

En este artículo, vamos a investigar en qué consiste la interfaz CGI y en particular haremos un análisis de la última especificación de WinCGI, que será la que emplearemos como interfaz CGI en nuestro servidor web. Para que la explicación no quede en mera información, haremos un programa WinCGI con Delphi plenamente funcional en cualquier servidor web que cumpla con dicha interfaz.

CGI

CGI ó Common Gateway Interface (Interfaz de Puerta Común) consiste en una especificación que permite conectar una aplicación a un servidor web. Define todas las reglas necesarias que deben cumplir tanto el servidor como las aplicaciones que dialoguen con él. De esta manera, al cumplir estas reglas, el servidor podrá comunicarse con cualquier programa que también se adapte a ellas. Así cualquier servidor que soporte la interfaz CGI, podrá comunicarse con cualquier programa CGI y cualquier programa CGI podrá, a su vez, funcionar en conjunto con cualquier servidor.

Como la CGI sólo define una interfaz, no entra en la especificación del lenguaje de programación con el que se deben crear los programas CGI. Sólo indica la forma en que debe realizarse la comunicación con la interfaz, pero no define cómo debe implementarse, ni sobre qué sistema operativo. Esto abre inmensas posibilidades ya que, en la práctica, se puede utilizar desde cualquier lenguaje interpretado del estilo de Perl en máquinas UNIX a cualquier lenguaje de programación compilado del estilo de Delphi en máquinas Intel bajo Windows.

El funcionamiento de la interfaz CGI en la práctica, sigue las siguientes pautas:

  1. El cliente lanza una petición a una URL, que en lugar de referirse a una página HTML, hace referencia a un programa ejecutable. Por ejemplo, introduce la URL: http://www.towercom.es/cgi/busca_datos?nombre=elastra donde busca_datos es un ejecutable en el servidor y nombre=elastra, un dato que se pasará como parámetro.
  2. El servidor web (que atiende las peticiones dirigidas a www.towercom.es) comprueba que busca_datos no es una página sino un ejecutable.
  3. De la propia petición, el servidor web extrae todos los datos que el cliente envía y que serán necesarios para ejecutar la aplicación.
  4. El servidor web ejecuta el programa busca_datos transmitiéndole todos los parámetros.
  5. El programa busca_datos se encarga de consultar en una base de datos, y de acuerdo a los parámetros de la petición, devuelve la información solicitada.
  6. El programa busca_datos genera una respuesta en la que se incluyen tanto los códigos de respuesta HTTP como la página HTML con los datos solicitados.
  7. Esta respuesta se le pasa al servidor web, que será el que efectivamente se la envíe al cliente.

Se puede apreciar cómo la interacción real se produce entre el cliente y el servidor web y entre el este último y proceso CGI, aunque la comunicación "lógica" se produce entre el cliente web y el programa CGI residente en el servidor.

WINCGI

La especificación CGI fue realizada pensando en máquinas UNIX. En éstas, la información CGI del servidor web se suministraba a través de la entrada/salida estándar y de variables de entorno. Sin embargo hay una serie de características que la hacen inutilizable en máquinas Windows (por ejemplo el manejo de stdin/stdout). Es por ello que los creadores del servidor Website (para Windows), transformaron la especificación para adaptarla a los ordenadores con entorno Windows. A esta nueva especificación se la denominó WinCGI. Con ella, en lugar de la entrada y salida estándar (stdin/stdout) se utilizan ficheros de intercambio, lo que permite programar aplicaciones con cualquier compilador: Delphi, Visual Basic, C++, etc. Actualmente su versión oficial es la 1.3.a.

La línea de comandos que el servidor web empleará para ejecutar una aplicación CGI (WinCGI, en realidad), constará del nombre del programa CGI ejecutable y de un nombre de fichero con extensión ini, que servirá de archivo de intercambio entre el servidor web y el programa CGI. Esto quiere decir que será una línea del estilo: C:\cgi-win\aplicacion_cgi.exe C:\temp\fichero_de_intercambio.ini

La aplicación aplicacion_cgi.exe será el programa CGI que invoca el servidor web ante una petición de un cliente, y el archivo fichero_de_intercambio.ini será el archivo que el servidor y el programa CGI utilizarán para informar y ser informados, respectivamente, de la petición que hagael cliente.

El hecho de que al realizar la especificación de WinCGI los autores se inclinasen por utilizar un archivo con extensión ini como archivo de intercambio, se debe la facilidad de manejo de este tipo de archivos en entornos Windows, ya que la propia API de Windows dispone de funciones de acceso directo a cualquier línea de cualquier sección de un fichero de inicialización. En nuestro caso esta labor será incluso más fácil, ya que existe una clase en Delphi (TIniFile), especializada en la lectura y escritura de este tipo de ficheros, y que convierte el manejo de los mismos en algo trivial.

El fichero ini es pues la parte estándar a la que deberán acomodarse tanto el servidor como el programa CGI si quieren entenderse. Es decir, no podremos inventarnos las secciones de este archivo, sino que éstas deberán seguir unas normas concretas.

En concreto este fichero consta de ocho secciones, con los siguientes títulos: Accept, System, ExtraHeaders, FormLiteral, FormExternal, FormHuge y FormFile. Cualquier dato de intercambio debe ir insertado en una de esas ocho secciones. Vemos estas secciones una a una, con sus posibles entradas y valores. Cada elemento de cada sección, se muestra en la forma entrada=valor. El valor será siempre una cadena (string), y si esta cadena está vacía, la entrada se omite.

SECCIÓN [CGI]

Esta sección contiene la identificación del programa CGI e información de acceso.

1. CGI Version. Version de la especificación WinCGI utilizada por el servidor.
2. Query String. Si la URL contiene el signo ? entonces, en esta entrada se guarda la cadena que sigue a dicho signo (que contendrá los parámetros de la consulta). El servidor debe suministrar este valor tal cual lo envió el cliente, quedando bajo la responsabilidad del programa CGI, la descodificación del mismo en las partes clave=valor.
3. Server Name. Nombre de dominio del servidor (para poder reconstruir la URL completa).
4. Server Port. Puerto a través del cual está escuchando el servidor.
5. Server Software. Nombre y versión del servidor web.
6. Referer. La URL de la página web que contiene el enlace al programa CGI (esta entrada puede no estar presente si el enlace fue escrito con el teclado o activado a través de un bookmark).
7. Request Method. Método de petición (GET ó POST) utilizado. El método POST suele utilizarse cuando los datos que deben transmitirse son tan largos que el método GET no puede manejarlos.
8. Request Protocol. Protocolo y versión, a través del cual se ha recibido la petición.
9. Remote Address. Dirección IP del cliente.
10. Remote Host. Nombre de dominio del cliente.
11. Content File. Ruta completa del fichero con los datos que envió el cliente (y que ha rellenado el servidor con esos datos).
12. Content Length. Longitud de los datos enviados.
13. Content Type. Tipo MIME del contenido de los datos
14. Executable Path. Ruta del fichero WinCGI que está siendo ejecutado.

A continuación se muestra un ejemplo de cómo podría ser esta sección :

[CGI]

CGI Version=WinCGI/1.3b

Referer=http://www.towercom.es/cgi.htm

Query String=articulo=Web Server 1/3

Server Name=www.towercom.es

Server Software=WebSitePro/2.0.36e

Server Port=80

Remote Host=http://www.towercom.es/

Remote Address=192.168.234.123

Request Protocol=HTTP/1.0

Request Method=POST

Content File=fichero_de_datos.dat

Content Length=2534

Content Type= multipart/form-data

Executable Path=c:\home\cgi-win\cgi_01.exe

SECCIÓN [ACCEPT]

Esta sección contiene la lista de los tipos de datos que acepta el cliente. La sintaxis será: tipo/subtipo=valor. Si el valor no se incluye, se entiende por defecto que es yes (si). Por ejemplo, esta sección podría ser como la siguiente:

[Accept]

image/gif=yes

image/x-xbitmap=yes

image/jpeg=yes

image/pjpeg=yes

*/*=yes

SECCIÓN [SYSTEM]

La sección System contiene información específica de la implementación del CGI.

1. GMT Offset. Tiempo (en segundos) que es necesario añadir a la hora GMT (Greenwich Mean Time, Hora Respecto al Meridiano Greenwich) para convertirla a la hora local.
2. Debug Mode. Informa si el servidor está en modo "depuración".
3. Output File. Ruta completa del fichero en el que el servidor web espera recibir los resultados del programa CGI.
4. Content File. Ruta completa del fichero que almacena el contenido de la petición.

Por ejemplo, esta sección podría ser como la siguiente:

[System]

GMT Offset=-3600

Debug Mode=no

Output File=c:\home\cgi-temp\salida_cgi.out

Content File=c:\home\cgi-temp\salida_cgi.con

SECCIÓN [EXTRA HEADERS]

Cabeceras "extra" incluidas en la petición (ver en el artículo anterior la especificación del HTTP). Por ejemplo:

[Extra Headers]

User Agent=Mozilla/4.03 [es] (Win95; I)

Connection=Keep-Alive

Pragma=no-cache

Host=localhost

SECCIÓN [FORM LITERAL]

Si se usa el método POST en la petición y ésta proviene a su vez de un formulario, en esta sección se escribirán las entradas correspondientes a las entradas del formulario HTML.

Los datos vendrán en la URL en la forma "entrada1=valor1&entrada2=valor2..." El servidor deberá dividir esta sentencia en pares "entradaX=valorX" y reemplazar los signos + por espacios en blanco (ya que los espacios en blanco se transmiten de esta forma en la URL).

Esas entradas son las que el servidor web introducirá en el fichero de extensión ini. Por ejemplo, esta sección podría ser como la siguiente:

[Form Literal]

Articulo1=ServidorWeb2.htm

Articulo2=ClienteEcho.htm

Nombre=Enrique de la

Apellidos=Lastra

Email=elastra@redestb.es

SECCIÓN [FORM EXTERNAL]

Si los valores de una entrada del formulario tienen más de 255 caracteres o contienen caracteres de control, el servidor web escribe el valor descodificado en un fichero temporal y añade una línea en esta sección.

Esta sección se podría parecer a lo siguiente:

[Form External]

field300chars=C:\home\cgi-temp\HS19AF6C.000 300

fieldwithlinebreaks=C:\home\cgi-temp\HS19AF6C.001 43

SECCIÓN [FORM HUGE]

Esta sección amplía a la anterior, y se utiliza cuando el valor de una entrada es mayor de 64K. En ese caso, el servidor no descodifica el valor, pero añade una línea en esta sección, en la que se indica el fichero de contenido donde aparecerá dicho valor y la posición del primer byte del valor, en dicho archivo. Por ejemplo:

[Form Huge]

field230K=c:\home\cgi-temp\HS19AF6C.002 276920If

SECCIÓN [FORM FILE]

Esta sección se utiliza cuando la petición contiene varios uploads y no la utilizaremos en ningún caso.

En el próximo número crearemos un programa basado en la interfaz WinCGI, de tal forma que con un formulario HTML (donde aparecerá la referencia al programa WinCGI, se podrá acceder a un determinado artículo de la serie "Creación de un servidor Web". Se indicarán los pasos para construir el proyecto en Delphi, además de incluir las páginas HTML, el código final del programa y el ejecutable final.


Banner 468x60
Explorer 4.0, Netscape 4.0. Resolución 800 x 600.
©Tower Communications 1.998.
Diseño: GRUPO ALBERTINA DE COMUNICACION.