Download icf_CGI

Document related concepts
no text concepts found
Transcript
Common
Gateway
Interface
Common Gateway Interface
Introducción
Generalidades
El elemento FORM de HTML
El lado del servidor
El lenguaje C
El lenguaje PERL
El lenguaje Java
Common Gateway Interface
Introducción a CGI
Introducción
La programación de CGI consiste en el
diseño y la escritura de programas que
reciben sus entradas desde una página Web.
Los formularios HTML son el método
preferido para enviar las entradas a los
programas CGI.
Introducción
Programar en CGI implica comprender y
utilizar HTML (Hyper-Text Mark Up
Language), HTTP (Hyper-Text Transport
Protocol) y la escritura de programas en
algún lenguaje de computador o shell del
Sistema Operativo (Borne Shell, Korn Shell,
C Shell, C, C++, PERL, Phyton, PHP Java,
...)
Common Gateway Interface
Generalidades
Generalidades
En la programación de CGIs, una solicitud es
hecha a una URL en una localización
reservada del servidor HTTP. Es el servidor
quien decide que localizaciones son
reservadas. Cuando una solicitud a tales
URLs es hecha, el servidor HTTP regresa la
salida del programa invocado al cliente.
Nota:
Apache, nuestro servidor Web, ha sido configurado para
considerar como CGIs a las aplicaciones que residan en:
$HOME/public_html/cgi-bin con extensión cgi
Generalidades
¿Cómo hace el servidor para capturar la salida de una
aplicación y dirigirla hacia al cliente?
#include <stdio.h>
FILE * popen(const char *command, const char *mode);
int pclose(FILE *stream);
La función popen() crea una tubería entre el programa que
hace el llamado y el comando ha ser ejecutado. El
argumento command consiste de una línea de comando
del shell, el modo es un modo de entrada/salida, r o w
Generalidades
#include <stdio.h>
#include <stdlib.h>
int main() {
char *cmd = "/usr/bin/ls *.c";
char buf[BUFSIZ];
FILE *ptr;
if ((ptr = popen(cmd, "r")) != NULL)
while (fgets(buf, BUFSIZ, ptr) != NULL)
(void) printf("%s", buf);
return 0;
}
Generalidades
Los datos pueden ser suministrados al CGI
adicionándolos al URL (usando el método
GET) o como parte de la entrada estándard
(usando el método POST).
También, una página Web puede capturar
información y enviarla al servidor usando
HTML o Java.
Generalidades
Cuando se utiliza HTML, se usa la etiqueta
FORM de HTML y los datos son enviados al
programa CGI cuando el usuario efectúa
ciertas acciones.
Una vez que los datos son enviados, el
programa CGI genera un documento HTML
con los resultados; que es enviado al usuario
para que los vea.
Common Gateway Interface
La etiqueta FORM de HTML
La etiqueta FORM de HTML
La etiqueta FORM
Las formas permiten crear elementos de
entrada asociados con un URL.
Programa CGI
GET o POST
<FORM action=”URL” method=”GET”>
...
</FORM>
La etiqueta FORM de HTML
El atributo action
Este atributo especifica el URL del programa
CGI que procesará los datos de la forma, o
una dirección de correo a donde serán
enviados los datos de la forma.
Cuando se usa una dirección de correo se
debe especificar el método POST
La etiqueta FORM de HTML
El atributo method
Este atributo especifica cómo serán
transmitidos los datos al servidor Web.
Cuando se usa GET los datos se añaden al
final de la URL, después de un cierre de
interrogación (?). De otro lado, con POST, los
datos son enviados aparte.
La etiqueta FORM de HTML
Atributo enctype
Este atributo especifica el método de
codificación utilizado antes de la transmisión.
El valor predefinido es: application/x-wwwform-urlencoded; cada espacio será
convertido a un signo de más ("+") y los
caracteres no alfabéticos a un signo de
porcentaje ("%") seguido por dos dígitos
hexadecimales.
La etiqueta FORM de HTML
También se colocará un signo de igualdad
("=") entre los nombres de los campos y sus
valores, y un ampersand ("&") entre las
entidades.
http://ainsuca/~alumnoXX/cgi-bin/p2.cgi?\
nombre=Colombia&\
capital=Bogot%E1&\
continente=Sur+Am%E9rica&\
area=1178907&\
poblacion=33000000\
Common Gateway Interface
El lado del servidor
El lado del servidor
CGI permite a las páginas Web comunicarse
con bases de datos u otros programas en un
sistema corriendo un servidor HTTP.
Técnicamente, CGI se refiere a la situación
en la que, un servidor arranca un programa
externo para procesar datos y generar
resultados.
El lado del servidor
Pasos ejecutados por un CGI
Un CGI debe llevar a cabo lo siguiente:
– Leer los datos.
– Enviar los encabezados HTTP.
– Enviar una línea en blanco.
– Generar un documento.
El lado del servidor
Leer los datos
Los datos de entrada se leen de acuerdo al
método utilizado para el envio de los mismos
(GET o POST).
El lado del servidor
Enviar los encabezados HTTP
El trabajo del CGI es imitar al servidor HTTP, parcial
o completamente. La forma más común es hacerlo
parcialmente, generando un conjunto incompleto de
encabezados y dejando al servidor HTTP llenar los
demás. En este caso el CGI debe enviar la
cabecera: Content-Type; normalmente, Content-Type:
text/html
El lado del servidor
Enviar una línea en blanco
Una línea en blanco (CRLF) separa las
cabeceras del documento principal.
Enviar el documento
El programa CGI debe enviar el documento de
acuerdo a la cabecera Content-Type. En la
mayoría de los casos se tratará de un
documento en formato HTML.
El lado del servidor
Programas CGI usando un script ejecutable
UNIX:
#!/bin/sh
echo “Content-Type: text/plain”
echo “”
echo “Texto plano desde un CGI por un script UNIX”
#!/bin/sh
echo “Content-Type: text/html”
echo “”
echo “<html><head><title>CGI Unix Shell</title>”
echo “</head><body><h1><i>”
echo “HTML desde un CGI con script UNIX”
echo “</i></h1></body></html>”
El lado del servidor
Leyendo datos GET
Cuando el cliente solicita una URL CGI a
través del método GET, ¿Cómo se pasan los
datos al programa?
El servidor HTTP crea una variable de
entorno llamada QUERY_STRING y luego
ejecuta el programa externo.
El lado del servidor
Para ilustrar este punto considérese el
ejemplo a continuación
#!/bin/sh
echo “Content-Type: text/plain”
echo “”
echo “Se recibieron los siguientes datos:”
echo “$QUERY_STRING”
Variable de entorno
El lado del servidor
Variables de entorno estándar CGI
AUTH_TYPE: esta variable da el método de
autenticación usado por el servidor
para validar a un usuario. Es tomada
dede la cabecera Auth-Scheme.
CONTENT-LENGTH: especifica el número de
caracteres contenidos en
QUERY_STRING. Es siempre
suministrada para solicitudes POST.
El lado del servidor
CONTENT_TYPE: especifica el tipo MIME del los
datos añadidos. Usualmente no
se especifica.
DOCUMENT_ROOT: regresa el camino de la
carpeta donde residen los
documentos HTML.
GATEWAY_INTERFACE: regresa la versión del
servidor CGI.
El lado del servidor
HTTP_XXX: este conjunto de variables mantiene
los contenidos de los encabezados
estándar HTTP. Una de ellas
corresponde al agente usuario:
HTTP_USER_AGENT.
PATH_INFO: contiene el camino virtual usado por el
programa CGI.
PATH_TRANSLATED: contiene el camino real
usado por los CGI.
El lado del servidor
QUERY_STRING: esta variable contiene los datos
suministrados por el usuario al
añadirlos a la URL después de
una ?. Llegará codificado si se
envía mediante formas HTML.
REMOTE_ADDR: especifica la dirección IP del
cliente.
REMOTE_HOST: especifica el nombre
completamente cualificado del
cliente.
El lado del servidor
REQUEST_METHOD: el método por medio del
cual fue hecho el requerimiento:
GET o POST.
SCRIPT_NAME: el URL del programa CGI.
SERVER_ADDR:
la dirección del servidor.
SERVER_NAME: el hostname del servidor.
SERVER_PORT: el número de puerto del servidor.
El lado del servidor
SERVER_PROTOCOL: la versión del protocolo
HTTP.
SERVER_SOFTWARE: el nombre y versión del
servidor HTTP.
El lado del servidor
Observe que lo único que necesita para crear
un programa CGI es un lenguaje que le
permita escribir a la consola; preferiblemente,
también le debe permitir leer una variable de
entorno. Puede utilizar cualquiera de los
siguientes programas: los shell UNIX
(Bourne, Korn, C, TCSh, Bash), C, C++,
VisualBasic, AppleScript, PERL, Phyton,
Java, ...
Common Gateway Interface
El lenguaje C
El lenguaje C
C es un lenguaje de propósito general que ha
sido estrechamente asociado con el sistema
UNIX en donde fue desarrollado puesto que
tanto el sistema como los programas que
corren en él están escritos en lenguaje C. Sin
embargo, el lenguaje no está ligado a ningún
sistema operativo o máquina.
El lenguaje C
Definición:
“C es un lenguaje de programación de
propósito general que ofrece como ventajas
economía de expresión, control de flujo y
estructuras de datos modernos y un rico
conjunto de operadores”
Dennis Ritchie
El lenguaje C
• Tipos de datos
– bool
– int
– char
– long
– short
– float
– double
Modificadores
unsigned
signed
El lenguaje C
For
While
for ([inicilizador];
[condicional];
[incremento]) {
expresiones;
}
while (condición) {
expresiones;
}
Do-while
do {
expresiones;
} while (condición);
El lenguaje C
En el lenguaje C no existen los
procedimientos, solamente hay funciones y
existe una función que corresponde a la
entrada de todo programa:
int main() {
/*...*/
return 0;
}
El lenguaje C
Para simplificarle la vida al programador hay
disponibles muchas funciones en Internet
que permiten manipular las solicitudes GETCGI utilizando el lenguaje C.
A continuación las implementaciones de tales
funciones, tomadas del servidor HTTP de
NCSA.
El lenguaje C
void getword(char *word, char *line, char stop) {
int x = 0,y;
for (x=0;((line[x]) && (line[x] != stop));x++)
word[x] = line[x];
word[x] = '\0';
if (line[x]) ++x;
y = 0;
while (line[y++] = line[x++]);
}
El lenguaje C
char *makeword(char *line, char stop) {
int x = 0,y;
char *word = (char *) malloc(sizeof(char) *
(strlen(line) + 1));
for (x=0; ((line[x]) && (line[x] != stop)); x++)
word[x] = line[x];
word[x] = '\0';
if(line[x]) ++x;
y=0;
while (line[y++] = line[x++]);
return word;
}
El lenguaje C
char *fmakeword(FILE *f, char stop, int *cl) {
int wsize, ll;
char *word;
wsize = 102400;
ll=0;
word = (char *) malloc(sizeof(char) * (wsize + 1));
while(1) {
word[ll] = (char)fgetc(f);
if (ll == wsize) {
word[ll+1] = '\0';
wsize += 102400;
word = (char*)realloc(word,sizeof(char)*(wsize+1));
}
El lenguaje C
--(*cl);
if ((word[ll] == stop) || (feof(f)) || (!(*cl))) {
if (word[ll] != stop) ll++;
word[ll] = '\0';
word = (char *) realloc(word, ll+1);
return word;
}
++ll;
}
}
El lenguaje C
char x2c(char *what) {
register char digit;
digit = (what[0] >= 'A' ?
((what[0] & 0xdf) - 'A')+10 :
(what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'A' ?
((what[1] & 0xdf) - 'A')+10 :
(what[1] - '0'));
return (digit);
}
El lenguaje C
void unescape_url(char *url) {
register int x,y;
for (x=0,y=0;url[y];++x,++y) {
if ((url[x] = url[y]) == '%') {
url[x] = x2c(&url[y+1]);
y += 2;
}
}
url[x] = '\0';
}
El lenguaje C
void plustospace(char *str) {
register int x;
for (x=0; str[x]; x++)
if (str[x] == '+')
str[x] = ' ';
}
int rind(char *s, char c) {
register int x;
for (x=strlen(s) - 1;x != -1; x--)
if(s[x] == c) return x;
return -1;
}
El lenguaje C
int getline(char *s, int n, FILE *f) {
register int i=0;
while(1) {
s[i] = (char)fgetc(f);
if (s[i] == CR)
s[i] = fgetc(f);
if ((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
s[i] = '\0';
return (feof(f) ? 1 : 0);
}
++i;
}
}
El lenguaje C
void send_fd(FILE *f, FILE *fd)
{
char c;
while (1) {
c = fgetc(f);
if (feof(f))
return;
fputc(c,fd);
}
}
int ind(char *s, char c) {
register int x;
for (x=0; s[x]; x++)
if (s[x] == c) return x;
return -1;
}
El lenguaje C
void escape_shell_cmd(char *cmd) {
register int x,y,l;
l = strlen(cmd);
for (x=0; cmd[x]; x++) {
if (ind("&;`'\"|*?~<>^()[]{}$\\\x0A",cmd[x]) != 1){
for(y=l+1; y>x; y--)
cmd[y] = cmd[y-1];
l++; /* length has been increased */
cmd[x] = '\\';
x++; /* skip the character */
}
}
}
El lenguaje C
Common Gateway Interface
El lenguaje PERL
El lenguaje PERL
Practical
Extraction and
Report
Languge.
Fue creado por Larry Wall quien lo describe como
más funcional que elegante. Hoy en día muchos
creen que es lenguaje ideal para el desarrollo de
scripts.
El lenguaje PERL
Tipos de datos
Escalares: todos los números y cadenas son
escalares. Los nombres de las variables
escalares comienzan por el signo $.
$cantidad = 100;
$descripcion = 'lápices';
$respuesta = $cantidad . $descripcion
print $respuesta; # 100lápices
El lenguaje PERL
Arreglos: un conjunto de valores escalares es
un arreglo. El nombre de una variable de
arreglo debe comenzar con un signo de
arroba @. Un literal de arreglo es una lista de
valores separados por comas y encerrados
en paréntesis redondos.
@frutas = (“naranjas”, “manzanas”, “fresas”);
El lenguaje PERL
Arreglos asociativos: son listas de valores
cuyo índice es una cadena.
%frutas = (“f”, “fresas”, “m”, “manzanas”, “l”, “limones”);
print $frutas{“m”}; # imprime manzanas
Existe un arreglo asociativo especial llamado
%ENV que almacena el contenido de las
variables de entorno.
El lenguaje PERL
if – else
While
if (condición ) {
expresiones;
} else {
expresiones;
}
while (condición ) {
expresiones;
}
For
for (inicio; fin; incremento ) {
expresiones;
}
@vocales=("a", "e", "i", "o", "u");
for ($i=0; $i<5; $i++){
print "$vocales[$i] ";
}
El lenguaje PERL
Until
For
until (condición ) {
expresiones;
}
foreach $escalar (@arreglo) {
expresiones;
}
@vocales=("a", "e", "i", "o", "u");
foreach $i (@vocales){
print "$i";
}
El lenguaje PERL
Subrutinas: En PERL, la subunidad básica de
código es la subrutina. Esta es familiar a una
función C.
Las subrutinas se pueden declarar en
cualquier lugar del código.
sub nombreDeLaSubrutina {
declaraciones;
}
El lenguaje PERL
#!/usr/bin/perl
# Impresión de las variables de entorno
#
print "Content-Type: text/html\n\n";
print
print
print
print
"<html>\n";
"<head><title>";
"Variables de entorno</title></head>\n";
"<body>\n";
print << "EOF";
<center>
<table border=2 cellpadding=10 cellspacing=10>
<th align=left><h3>Variables de Entorno desde
PERL</h3>
<th align=left><h3>Contenido</h3><tr>
EOF
El lenguaje PERL
foreach $var (sort keys(%ENV)){
print "<td> $var <td> $ENV{$var}<tr>\n";
}
print << "EOF"
</table>
</body>
</html>
EOF
El lenguaje PERL
Para invocar a una subrutina se antepone al
nombre de la subrutina el carácter &
(ampersand).
El valor de retorno de una subrutina es el
valor de la última instrucción ejecutada. Si
así se desea se puede retornar un valor
usando return;
El lenguaje PERL
#!/usr/bin/perl
#
$escalar = &subrutina;
print "valor de retorno: $escalar\n"
@arreglo = &subrutina;
print "valor de retorno: @arreglo\n"
sub subrutina {
print "imprime y retorna.\n";
%perl prueba.pl
quiereunarreglo ? (a, b, c) : 0;
imprime y retorna.
}
valor de retorno 0
imprime y retorna.
valor de retorno: a b c
%
El lenguaje PERL
Primeros pasos para el manejo de un formulario
sub getFormData {
my($buffer) = "";
if ($ENV{'REQUEST_METHOD'} eq 'GET') {
$buffer = $ENV{'QUERY_STRING'};
}
else {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
}
El lenguaje PERL
Decodificación de los datos
sub decodeURL {
$_ = shift;
tr/+/ /;
s/%(..)/pack('c', hex($1))/eg;
return($_);
}
El lenguaje PERL
Separe los parámetros y los campos de los valores:
foreach (split(/&/, $buffer)) {
my($key, $value) = split(/=/, $_);
$key = decodeURL($key);
$value = decodeURL($value);
%{$hashRef}->{$key} = $value;
}
Common Gateway Interface
CGI con Java
CGI con Java
Recordemos que Java es un lenguaje de
programación de propósito general, orientado
a objetos, concurrente y multiplataforma.
CGI con Java
Para poder utilizar un programa en Java
como un programa CGI se debe contar con
un modo de pasarle como argumento la
variable de entorno QUERY_STRING, así
#!/usr/bin/sh
/usr/java/bin/java nombrePrograma “$QUERY_STRING”
CGI con Java
La clase URLDecoder, del paquete java.util,
contiene un método para convertir desde un
formato MIME llamado “x-www-formurlencode” a un String.
Para hacer la conversión cada carácter es
examinado así:
Nota: URLDecoder está disponible desde Java 2
CGI con Java
Los caracteres ASCII de la 'a' a la 'z', de 'A' a
'Z' y de '0' a '9' se dejan igual.
El signo más ('+') es convertido a un espacio
(' ').
Los demás caracteres son representados por
cadenas de 3 caracteres que empiezan por
un signo de porcentaje, “%xy” es la
representación hexadecimal de los más
bajos bits del caracter.
CGI con Java
Veamos un modelo del uso de esta clase:
//...
String s = “continente=Sur+Am%E9rica”;
try {
System.out.println(decode(s));
} catch(Exception e) {}
//...
...
continente=Sur América
...
CGI con Java
Como se sabe, los parámetros en un GET
CGI, pasan en la variable de entorno
QUERY_STRING. Para leerlos debemos
separar las cadenas delimitadas por un signo
ampersand &.
Java cuenta con una clase que hace este
trabajo: java.util.StringTokenizer
CGI con Java
StringTokenizer pone a su disposición:
– bool hasMoreTokens();
– String nextToken();
Estos métodos permiten saber cuando hay
más señales y cual es la cadena.
En el constructor se especifica la marca o
señal que se usa.
CGI con Java
//...
private String cuerpo() {
StringTokenizer t =
new StringTokenizer(argumento, "&");
String mensaje = "<ul>";
while (t.hasMoreTokens()) {
mensaje += "<li>" +
t.nextToken() + "</li><br>\n";
}
mensaje += "</ul>";
return mensaje;
}
//...
Bibliografía
Afergan Michael y otros, Programación en Web 6 en 1, QUE
Cay S. Horstmann & Gary Cornell, Core Java 2, volume I Fundamentals, Sun Microsystems Press, Prentice Hall.
Hall, Marty, Core Web Programming, Prentice Hall, 1998
Herrmann, Eric, Programación en CGI con PERL 5, Prentice Hall.
Kernighan, Brian W., Ritchie Dennis M., El lenguaje de
programación C, Prentice Hall, 2da. Edición
Medinets, David, Perl 5 by Example, Que
Bibliografía
Internet:
HyperText Transfer Protocol -- HTTP/1.1
http://www.w3.org/pub/WWW/Protocols/
The WWW Common Gateway Interface Version 1.1
http://www.ietf.org/ietf/