Programaci�n: CGI: Programaci�n

En este tutorial crearemos un script CGI que env�e un correo y devuelva una p�gina que indique que el correo ha sido enviado. Sin embargo, los conceptos ser�n bastante geniales para permitir que el script pueda ser adaptado a cualquier proyecto donde sea necesario enviar un correo desde un script. Tambi�n veremos brevemente como examinar las �reas de texto l�nea por l�nea.

Como siempre, cuando empezamos, necesitaremos un formulario.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

<html>
<!--Javier P�rez Delgado ([email protected]) All Rights Reserved -->
<head>

<link rev=made href="mailto:[email protected]">
<title>Enviar correo desde un script CGI</title>
</head>
<body>
<P>Este formulario enc�a correo a la direcci�n de la persona mostrada.</P>
<form method="POST" action="http://www.ctv.es/USERS/cgi-bin/mail.pl">
<P>Tu direcci�n: <INPUT NAME="De" SIZE=36></P>
<P>Tu URL: <INPUT NAME="xurl" SIZE=36></P>
<P>Subject: <INPUT NAME="subject" SIZE=40></P>
<P>Mensaje:</P>
<P><TEXTAREA name="body" rows=10 cols=60></TEXTAREA></P>
<P><input type="submit" value="Enviar mansaje">
<input type="reset" value="Borrar todo"></P>
</FORM>
</P>
</body>
</html>

Ahora pasaremos al script. Como siempre deber� empezar con una llamada al perl, algunos comentarios y una llamada a la rutina ReadParse, en la librer�a cgi-lib.pl. Tambi�n haremos verificaciones de que el cuerpo del mensaje no est� vac�o, y de que la direcci�n contiene una arroba (@). Otra validaci�n ser� para comprobar que de pasan argumentos, lo pondremos porque la gente tiene tendencia a llamar a los scripts de correo sin argumentos (eg: no desde un formulario), no entiendo por qu�. Para comprobar que no hay argumentos, simplemente examinaremos si el vector %in que la librer�a cgi-lib.pl nos devuelve tiene alguna tecla. Recuerda, que ning�n argumento, significa que no nos han pasado nada, sin embargo, alguien puede pasar los argumentos en blanco, de aqu� las dos comprobaciones. La manera de comprobar los valores de las teclas del vector es usar la funci�n keys(). Esta funci�n espera un array asociativo como argumento. Simplemente comprobaremos que devuelve algo, imprimiendo un mensaje de error si no hay teclas. El c�digo pude ser este:

if (!keys(%in)) {
# niguna tecla ha sido pasada, imprimir mensaje de error, y si es apropiado salir.
}

Date cuenta de que el signo '!' al principio de la llamada a keys(), significa 'no' o negaci�n. Quiere decir que si keys() no devuelve nada (falso), ser� negado para que sea cierto y el if se ejecute. Ahora que hemos validado las entradas, y se pueden realizar m�s comprobaciones, necesitaremos enviar la carta. Para ello necesitaremos un programa que acepte una carta del stdin. Luego usaremos sendmail en el ejemplo. Si no est�s en un entorno Unix, necesitar�s otro programa apropiado para hacerlo. Como no conozco otro tipo de sistemas, no puedo hacer ninguna recomendaci�n.

Usar este programa ser� similar a escribir en un fichero. Necesitamos abrir el programa para aceptar la entrada, escribir al FILEHANDLE. Abrir un programa que espera entradas por el stdin es bastante f�cil em Perl. Adem�s, es muy f�cil pasar el argumento de la l�nea de comandos. En este ejemplo, abriremos sendmail, y diremos que busque en la carta la direcci�n de destino.

open(MAIL,"|/usr/lib/sendmail -t");

Como se puede observar, es igual que una llamada a fichero, pero los s�mbolos '>' o '<' han sido sustituidos por un '|' (tuber�a). Esto indica que lo que hay detr�s de la tuber�a es un ejecutable, y que lo que imprimamos en este FILEHANDLE se deber� pasar como entrada a el programa ejecutable.

Nota: No he comprobado si la operaci�n anterior termin� con �xito, pero deber�amos hacerlo. La manera m�s sencilla de hacerlo, es apoyarnos en que el comando open devuelve true cuando ha tenido �xito. Solo debemos hacer un OR entre el comando open y otro comando conociendo que ese comando ser� ejecutado si el open falla. El ejemplo de abajo realiza un OR con el comando die. Este comando imprime un mensaje de error y sale del programa.

open(MAIL,"|/usr/lib/sendmail -t") || die "La llamada a sendmail ha fallado";

El imprimir la carta funciona como esperamos. Recuerda, sin embargo, que estamos imprimiendo un trozo de e-mail, por lo que deberemos poner las cabeceras adecuadas, un l�nea en blanco y el cuerpo del mensaje. Puedes echar un vistazo a un e-Mail que hayas recibido y comprobar las cabeceras. Describir� abajo lo m�s importante. Los comentarios ser�n de ayuda.

# Esta es la l�nea 'para'. Si tenemos el nombre y la direcci�n, escribiremos
# primero el nombre y luego la direcci�n entre <>
print MAIL "To: $in{'De'}\n";

# Esta es la l�nea 'De'. Pondremos el mismo nombre en la l�nea 'De' y en la 'para'
# Recuerda que no hay seguridad comprobando el email, por ello estas l�neas
# pueden ser falsificadas. NO FALSIFIQUES EL EMAIL, no es divertido y en algunos lugares
# es un delito.
print MAIL "From: $in{De}\n";

# Esta es la l�nea 'contestar a'. Esta l�nea se incluye debido a que algunos programas
# son bastante tontos y no siempre responden a la l�nea 'De'.
# Al menos respetar�n esta l�nea.
print MAIL "Reply-To: $in{De}\n";

# Lo siguiente son cabeceras X. Son creadas por el usuario y pueden contener
# todo lo que desees. Incluyo una l�nea de descripci�n
# tambi�n he escrito las l�neas REMOTE_HOST, REMOTE_ADDR, y REMOTE_USER para
# ayudar al seguimiento (traking) de la carta.
# Solo escribo la l�nea X-URL si el usuario ha dado una url. Este tipo
# de comprobaci�n probablemente hecha tambi�n en el X-Remote-Host y X-Remote-User

print MAIL "X-mailer: Mail.pl, a cgi-bin script at http://www.ctv.es/users/jperez/www/tutor/ /index.html\n";
print MAIL "X-Remote-Host: $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n";
print MAIL "X-Remote-User: $ENV{'REMOTE_USER'}\n";
print MAIL "X-disclaimer: La l�nea De: puede estar falsificada ";
print MAIL "No confiar en un 100% sobre la integridad de este mail. ";
print MAIL "No somos responsables de este correo de ninguna manera\n";
if ($in{xurl} ne "") {
print MAIL "X-URL: $in{xurl}\n";
}


# Finalmente escribimos la famosa l�nea del asunto.
# Presatr atenci�n en la segunda nueva l�nea. Esta es la l�nea
# que va a separar el encabezado del cuerpo del mensaje.
print MAIL "Subject: $in{subject} (WWW generated email)\n\n";

# Ahora vamos a escribir elcuerpo del mensaje.
print MAIL $in{'body'};

Solo quedan dos cosas. Primero debemos cerrar la conexi�n con sendmail. Segundo debemos imprimir una p�gina ense�ando al usuario la carta que env�a.

Para cerrar la conexi�n, usaremos el comando close, justo como en cualquier otro manejador:

close(MAIL);

Imprimir la respuesta no es diferente a las otras p�ginas generadas din�micamente que ya hemos creado anteriormente. Deberemos dividir el campo TEXTAREA en l�neas colocando un <BR> al final de cada una. Esto se hace principalmente para demostrar como se divide un campo de texto. Recuerda sin embargo que html no respeta las nuevas l�neas. Con ello se consigue el poder hacer los p�rrafos de manera m�s clara, pero el beneficio de hacerlo es cuestionable.

El valor del campo body (cuerpo del mensaje), no es m�s que un conjunto de frases separadas con un retorno de carro. Podemos usar la funci�n split() para separarlas. Esta funci�n necesita dos par�metros: la cadena o car�cter para separar y la variable a separar, y retorna un array con los elementos separados. Usaremos split en un bucle foreach:

foreach $l (split('\n',$in{'body'})) {
print "$l<BR>\n";
}

Como se puede ver separa la variable $in{'body'} en partes cada nueva l�nea, y la imprime seguida de un <BR>.

Manual de Perl

El Evangelio de Perl Leerlo off-line
Un excelente manual para aquellos que quieran introducirse a este lenguaje.

 

Hosted by www.Geocities.ws

1