Manual de uso de CGI


Que es un CGI

CGI (Common Gateway Interface) es el interfaz normalizado que utilizan los servidores de WWW (httpd) para comunicarse con aplicaciones externas. El CGI permite al servicio WWW interactuar con otras aplicaciones, servicios de información o bases de datos.

El CGI especifica como se pasan los datos desde el servicio WWW a una aplicación externa y como se recuperan los resultados. Como todo en el WWW, el interfaz CGI es simple pero muy potente.

El CGI define dos mecanismos para pasar datos desde el servicio WWW a una aplicación externa, el primero utiliza variables de entorno y el segundo la entrada estandard. La recuperación de resultados se produce siempre a través de la salida estandard.

El primer método recibe el nombre de método GET y se utiliza principalmente para búsquedas en documentos por palabra clave. El segundo método, llamado POST, se utiliza para procesar el contenido de formularios.

Junto con las opciones del servidor el protocolo CGI se basa tambien en los mecanismos de los clientes para introducir información. A continuación revisamos estos mecanismos.

ISSEARCH

Introduciendo la directiva &ltISSEARCH> en la página HTML, esta página se convierte en un documento de consulta. Estos documentos se generan por aplicaciones CGI y en ellos el cliente WWW añade un cuadro de introducción de texto con el cual se pueden realizar consultas al documento. Las consultas se resuelven por el CGI que generó la página.

Las consultas ISSEARCH se resuelven por el método GET.

IMAGEMAP

El método IMAGEMAP registra pulsaciones del ratón sobre una imagen. Por este método es posible conocer la posición de pulsación del ratón en el cliente WWW.

El uso principal de las imágenes pinchables es la creación de menús gráficos.

EL método IMAGEMAP se gestiona por una aplicación CGI específica que se incluye en la mayoria de servidores HTTP. En el NCSA HTTPD la aplicación se denomina imagemap, en CERN HTTPD la aplicación se denomina htimage.

Los CGI que gestionan la información del método IMAGEMAP utilizan mascaras donde se definen las acciones a ejecutar dependiendo de la posición de la imagen donde se haya pinchado.

Un ejemplo claro es la barra de menus que tenemos instalada en nuestra BBS, su configuración es la siguiente:

Formularios

Los formularios son un elemento esencial del CGI. Los formularios permiten introducir en un cliente WWW información estructurada que puede utilizarse como datos de entrada de una aplicación CGI. Para el soporte de formularios el lenguaje HTML permite la definición de de distintos tipos de campos.

Un formulario en HTML se limita con los marcadores &ltFORM> y </FORM>. Un formulario puede incluirse en cualquier parte de un documento HTML, y sobre un mismo documento pueden insertarse distintos formularios.

La sintaxis del marcador de formulario es la siguiente:

&ltFORM METHOD="método" ACTION="URL del CGI">

Campos en formularios

Los formularios en HTML soportan distintos tipos de campos. La sintaxis general del marcador de campo en HTML es la siguiente:

&ltINPUT TYPE="tipo" NAME="nombre" VALUE="valor">

Los típos válidos de campos de formulario son los siguientes:
<FORM ACTION="http://www.infase.es/cgi-bin/mail?sobreve" METHOD=POST>

Estos controles admiten los modificadores siguientes, ya indicados:

Otros controles tienen una sintaxis especial.

La siguiente contrucción permite crear un control de selección sobre una lista de opciones predefinidas.

&ltSELECT NAME="nombre"> &ltOPTION &gtTexto de la seleccion 1 &ltOPTION &gtTexto de la seleccion 2


El control &ltOPTION> permite los modificadores siguientes:

El siguiente control permite introducir texto de cualquier longitud.

&ltTEXTAREA NAME="nombre">. Texto que aparecerá en el recuadro. Es opcional.

Este control acepta los atributos específicos

Codificación de la información de un formulario

El contenido de un formulario se codifica para su transmisión entre el cliente y el servidor HTTP, y de este hasta la aplicación CGI. Esta codificación asocia el contenido de los campos con el nombre de los mismos.

La sintaxis general de esta codificación es la siguiente:

campo=contenido&campo=contenido&... Una colección de parejas nombre de campo, contenido del campo separadas por simbolos '&' y donde los espacios en 'contenido' se sustituyen por signos '+'.

Para facilitar el proceso de extracción de la información desde este formato, los servidores de HTTP suelen incluir una libreria de funciones. A modo de ejemplo, el servidor HTTPD de NCSA define una libreria con las funciones para extraer las parejas nombre de campo - valor de la información recibida por el CGI.

Estas funciones se utilizan por las aplicaciones CGI como muestra el siguiente listado:

typedef struct { char name[128]; char val[128]; } entry; int m,x; cl = getenv("QUERY_STRING"); for(x=0;cl[0] != '\0';x++) { m=x; getword(entries[x].val,cl,'&'); plustospace(entries[x].val); unescape_url(entries[x].val); getword(entries[x].name,entries[x].val,'='); }

Método GET

En el método GET la aplicación CGI recibe la información a través de variables de entorno. El proceso de lanzamiento de una aplicación CGI con el método GET es el siguiente.
  1. El cliente WWW solicita un servicio de una aplicación CGI.
  2. El servidor HTTPD recibe la solicitud y los datos de entrada.
  3. El servidor crea un entorno y crea variables en el con los datos de entrada.
  4. El servidor ejecuta la apliación CGI en este entorno.
  5. La aplicación CGI procesa las variables de entorno y recupera los datos de entrada.
  6. La aplicación CGI se ejecuta produciendo un resultado sobre su salida estandard.
  7. EL servidor HTTP redirecciona la salida estandard de la aplicación CGI hacia el cliente WWW.
  8. El cliente WWW recibe el resultado de su consulta.

A continuación incluimos el listado de una aplicación CGI que desarrolla el método GET. Como puede observarse la información pasa a la aplicación CGI a través de la variable de entorno QUERY_STRING.

/* * Ejemplo de aplicación CGI operada * a través de la acción GET * * INFASE Comunicaciones S.L. 1995 * * Basada en scripts originales de NCSA HTTPD */ #include #include /* * Funciones de análisis de los datos del formulario * Las funciones estan definidas en util.c */ typedef struct { char name[128]; char val[128]; } entry; void getword(char *word, char *line, char stop); char x2c(char *what); void unescape_url(char *url); void plustospace(char *str); main(int argc, char *argv[]) { entry entries[10000]; register int x,m=0; char *cl; /* * Imprime la cabecera que indica al servidor HTTP que los * datos que siguen a continuación son de tipo texto html */ printf("Content-type: text/html%c%c",10,10); /* * Comprueba que los parámetros del programa se pasan * por el método GET * &ltFORM METHOD="GET" ACTION="/cgi-bin/post"> */ if(strcmp(getenv("REQUEST_METHOD"),"GET")) { printf("Esta aplicación debe activarse por el método GET\n"); exit(1); } /* * En el método GET la información pasa al cgi * a través de la variable de entorno QUERY_STRING */ cl = getenv("QUERY_STRING"); if(cl == NULL) { printf("No hay información para decodificar.\n"); exit(1); } /* * La sintaxis de la información es la siguiente * campo=contenido&campo=contenido&... * Los espacios en 'contenido' se sustituyen por signos '+'. * Las siguientes funciones extraen la información. */ for(x=0;cl[0] != '\0';x++) { m=x; getword(entries[x].val,cl,'&'); plustospace(entries[x].val); unescape_url(entries[x].val); getword(entries[x].name,entries[x].val,'='); } /* * Imprime el resultado del programa a través de la salida * estándard. En este caso imprime el valor de todos los * campos rellenados por el usuario. Imprime el resultado * formateado en HTML. */ printf("&ltH1&gtResultados de la consulta"); printf("He recibido las siguientes parejas de valores:&ltp>%c",10); printf("&ltul>%c",10); for(x=0; x <= m; x++) printf("&ltli> &ltcode>%s = %s%c",entries[x].name, entries[x].val,10); printf("%c",10); }

Método POST

El método POST es el método recomendado para el paso de información de formulario a una aplicación CGI. En este método la información se pasa a través de la entrada estandar de la aplicación CGI.

El proceso de lanzamiento de una aplicación CGI con el método POST es el siguiente.

  1. El cliente WWW solicita un servicio de una aplicación CGI.
  2. El servidor HTTPD recibe la solicitud y los datos de entrada.
  3. El servidor ejecuta la apliación CGI pasandole la información a través de la entrada estandar.
  4. La aplicación CGI procesa su entrada estandard y recupera los datos de entrada.
  5. La aplicación CGI se ejecuta produciendo un resultado sobre su salida estandard.
  6. EL servidor HTTP redirecciona la salida estandard de la aplicación CGI hacia el cliente WWW.
  7. El cliente WWW recibe el resultado de su consulta.

/* * Ejemplo de aplicación CGI operada * a través de la acción POST * * INFASE Comunicaciones S.L. 1995 * * Basada en scripts originales de NCSA HTTPD */ #include &ltstdio.h> #include &gtstdlib.h> #define MAX_ENTRIES 10000 /* * Funciones de análisis de los datos del formulario * Las funciones estan definidas en util.c */ typedef struct { char *name; char *val; } entry; char *makeword(char *line, char stop); char *fmakeword(FILE *f, char stop, int *len); char x2c(char *what); void unescape_url(char *url); void plustospace(char *str); main(int argc, char *argv[]) { entry entries[MAX_ENTRIES]; register int x,m=0; int cl; /* * Imprime la cabecera que indica al servidor HTTP que los * datos que siguen a continuación son de tipo texto html */ printf("Content-type: text/html%c%c",10,10); /* * Comprueba que los parámetros del programa se pasan * por el método POST * &ltFORM METHOD="POST" ACTION="/cgi-bin/post"> */ if(strcmp(getenv("REQUEST_METHOD"),"POST")) { printf("Esta aplicación debe activarse por el método POST\n"); exit(1); } /* * Comprueba que los datos de entrada corresponden al contenido * de un formulario */ if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) { printf("La entrada a la aplicación no es un formulario\n"); exit(1); } /* * Analiza los datos de entrada y los introduce en un vector de * parejas de valores, siendo el primero el nombre del campo * y el segundo el valor que contiene. El nombre se declara en la * definición del formulario. El valor es el introducido por el * usuario. Todos los campos se tratan como cadenas de caractéres. * * El campo &ltINPUT TYPE="text" NAME="Prueba"> */ /* * En el método POST la información pasa al cgi * a través de la entrada estandar (stdio) */ cl = atoi(getenv("CONTENT_LENGTH")); /* * La sintaxis de la información es la siguiente * campo=contenido&campo=contenido&... * Los espacios en 'contenido' se sustituyen por signos '+'. * Las siguientes funciones extraen la información. */ for(x=0;cl && (!feof(stdin));x++) { m=x; entries[x].val = fmakeword(stdin,'&',&cl); plustospace(entries[x].val); unescape_url(entries[x].val); entries[x].name = makeword(entries[x].val,'='); } /* * Imprime el resultado del programa a través de la salida * estándard. En este caso imprime el valor de todos los * campos rellenados por el usuario. Imprime el resultado * formateado en HTML. */ printf("&ltH1&gtResultados de la consulta"); printf("He recibido las siguientes parejas de valores:&ltp>%c",10); printf("&ltul>%c",10); for(x=0; x <= m; x++) printf("&ltli> &ltcode>%s = %s%c",entries[x].name, entries[x].val,10); printf("%c",10); }

Paso de información como argumentos del programa CGI

Existe un tercer método de paso de información desde el cliente WWW y la aplicación WWW. Este método es complementario a los métodos POST y GET.

La información, en este método se añade al URL en el cliente WWW. La información a la derecha del URL se transfiere como argumento de la aplicación CGI. Podemos utilizar el caracter '?' para separar distintos argumentos la aplicación CGI.

A continuación a modo de ejemplo incluimos el listado de una aplicación que procesa la información de URL. Este programa envia por correo electrónico, el contenido de un formulario a los usuarios indicados en el URL.

La sintaxis del URL es:

&ltFORM METHOD="POST" ACTION="/cgi-bin/mail?dirección-correo">

'/cgi-bin/mail' es el nombre del URL y 'dirección-correo' es una dirección válida de correo electrónico.

/* * CGI para envio de un formulario por correo * * sintaxis: * mail?usuario[,usuario[,usuario ...]] * * INFASE Comunicaciones 1995 */ #include &ltstdio.h> #include &ltstdlib.h> #define MAX_ENTRIES 10000 typedef struct { char *name; char *val; } entry; char *makeword(char *line, char stop); char *fmakeword(FILE *f, char stop, int *len); char x2c(char *what); void unescape_url(char *url); void plustospace(char *str); void Error(char *msg) { printf("&ltB&gtERROR&ltB>&ltP>\n"); printf("%s",msg); } main(int argc, char *argv[]) { entry entries[MAX_ENTRIES]; register int x,m=0; int cl; FILE *phfp; char cmdstr[300]; int i; printf("Content-type: text/html%c%c",10,10); if (argc != 2) { printf("número de argumentos erroneo. Debe indicar el destinatario del mail%c",10); exit(0); } if(strcmp(getenv("REQUEST_METHOD"),"POST")) { printf("Este script debe referenciarse con METHOD a POST.\n"); exit(1); } if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) { printf("La entrada no es un formulario"); exit(1); } cl = atoi(getenv("CONTENT_LENGTH")); for(x=0;cl && (!feof(stdin));x++) { m=x; entries[x].val = fmakeword(stdin,'&',&cl); plustospace(entries[x].val); unescape_url(entries[x].val); entries[x].name = makeword(entries[x].val,'='); } /* envia por correo el mensaje generado */ sprintf(cmdstr,"/bin/mail %s",argv[1]); phfp = popen(cmdstr,"w"); if (phfp == NULL) Error("Error al abrir comando mail"); for(x=0; x <= m; x++) fprintf(phfp,"%s = %s%c",entries[x].name, entries[x].val,10); fprintf(phfp,"\n.\n"); if ( pclose(phfp) ) Error("Error al cerrar comando mail"); /* devuelve el mensaje de aceptación al usuario */ printf("&ltH1&gtOperación procesada"); printf("Su operación ha sido procesada."); printf("&ltP>"); printf("&ltA HREF=\"/\"&gtVolver a la portada"); printf("&ltHR>"); }

Variables de entorno

Existen distintas variables de entorno que utilizan el servidor HTTPD y la aplicación CGI para intercambiar información adicional. Esta información permite al cliente conocer información adicional sobre los datos de entrada o sobre el estado del servidor.

A continuación incluimos un programa CGI que imprime el contenido de las variables de entorno.

#!/bin/sh echo Content-type: text/plain echo echo CGI/1.0 test script report: echo echo argc is $#. argv is "$*". echo echo SERVER_SOFTWARE = $SERVER_SOFTWARE echo SERVER_NAME = $SERVER_NAME echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE echo SERVER_PROTOCOL = $SERVER_PROTOCOL echo SERVER_PORT = $SERVER_PORT echo REQUEST_METHOD = $REQUEST_METHOD echo HTTP_ACCEPT = "$HTTP_ACCEPT" echo PATH_INFO = "$PATH_INFO" echo PATH_TRANSLATED = "$PATH_TRANSLATED" echo SCRIPT_NAME = "$SCRIPT_NAME" echo QUERY_STRING = "$QUERY_STRING" echo REMOTE_HOST = $REMOTE_HOST echo REMOTE_ADDR = $REMOTE_ADDR echo REMOTE_USER = $REMOTE_USER echo AUTH_TYPE = $AUTH_TYPE echo CONTENT_TYPE = $CONTENT_TYPE echo CONTENT_LENGTH = $CONTENT_LENGTH

Ejemplos CGI

Inicio Cursos Portada

© INFASE Comunicaciones S.L. 1995
Hosted by www.Geocities.ws

1