{"id":10603,"date":"2017-10-25T07:56:13","date_gmt":"2017-10-25T07:56:13","guid":{"rendered":"http:\/\/localhost\/datacraft2023\/internet-progcgi\/"},"modified":"2022-08-18T07:33:36","modified_gmt":"2022-08-18T10:33:36","slug":"internet-progcgi","status":"publish","type":"page","link":"http:\/\/localhost\/datacraft2023\/internet-progcgi\/","title":{"rendered":"Internet: programando CGIs: formulario de email"},"content":{"rendered":"

\n

\u00a0Volver al Indice –\u00a0Internet y Tutoriales de Dise\u00f1o Web<\/a><\/h2>\n

\"Internet:<\/p>\n

Por Alejandro Franco –\u00a0cont\u00e1ctenos<\/a><\/h2>\n

En este tutorial crearemos un script CGI que env\u00ede un correo y devuelva una p\u00e1gina que indique que el correo ha sido enviado. Sin embargo, los conceptos ser\u00e1n bastante geniales para permitir que el script pueda ser adaptado a cualquier proyecto donde sea necesario enviar un correo desde un script. Tambi\u00e9n veremos brevemente como examinar las \u00e1reas de texto l\u00ednea por l\u00ednea.
\nComo siempre, cuando empezamos, necesitaremos un formulario.<\/p>\n

<!DOCTYPE HTML PUBLIC “-\/\/IETF\/\/DTD HTML\/\/EN”>
\n<html>
\n<head>
\n<link rev=made href=”mailto:jperez@dominio.com”>
\n<title>Enviar correo desde un script CGI<\/title>
\n<\/head>
\n<body>
\n<P>Este formulario enc\u00eda correo a la direcci\u00f3n de la persona mostrada.<\/P>
\n<form method=”POST” action=”http:\/\/www.dominio.com\/cgi-bin\/mail.pl”>
\n<P>Tu direcci\u00f3n: <INPUT NAME=”De” SIZE=36><\/P>
\n<P>Tu URL: <INPUT NAME=”xurl” SIZE=36><\/P>
\n<P>Subject: <INPUT NAME=”subject” SIZE=40><\/P>
\n<P>Mensaje:<\/P>
\n<P><TEXTAREA name=”body” rows=10 cols=60><\/TEXTAREA><\/P>
\n<P><input type=”submit” value=”Enviar mansaje”>
\n<input type=”reset” value=”Borrar todo”><\/P>
\n<\/FORM>
\n<\/P>
\n<\/body>
\n<\/html><\/p>\n

Ahora pasaremos al script. Como siempre deber\u00e1 empezar con una llamada al perl, algunos comentarios y una llamada a la rutina ReadParse, en la librer\u00eda cgi-lib.pl. Tambi\u00e9n haremos verificaciones de que el cuerpo del mensaje no est\u00e1 vac\u00edo, y de que la direcci\u00f3n contiene una arroba (@). Otra validaci\u00f3n ser\u00e1 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\u00e9. Para comprobar que no hay argumentos, simplemente examinaremos si el vector %in que la librer\u00eda cgi-lib.pl nos devuelve tiene alguna tecla. Recuerda, que ning\u00fan argumento, significa que no nos han pasado nada, sin embargo, alguien puede pasar los argumentos en blanco, de aqu\u00ed las dos comprobaciones. La manera de comprobar los valores de las teclas del vector es usar la funci\u00f3n keys(). Esta funci\u00f3n espera un array asociativo como argumento. Simplemente comprobaremos que devuelve algo, imprimiendo un mensaje de error si no hay teclas. El c\u00f3digo pude ser este:<\/p>\n

if (!keys(%in)) {
\n# ninguna tecla ha sido pulsada, imprimir mensaje de error, y si es apropiado salir.
\n}<\/p>\n

Date cuenta de que el signo ‘!’ al principio de la llamada a keys(), significa ‘no’ o negaci\u00f3n. Quiere decir que si keys() no devuelve nada (falso), ser\u00e1 negado para que sea cierto y el if se ejecute. Ahora que hemos validado las entradas, y se pueden realizar m\u00e1s 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\u00e1s en un entorno Unix, necesitar\u00e1s otro programa apropiado para hacerlo. Como no conozco otro tipo de sistemas, no puedo hacer ninguna recomendaci\u00f3n.<\/p>\n

\n

Usar este programa ser\u00e1 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\u00e1cil em Perl. Adem\u00e1s, es muy f\u00e1cil pasar el argumento de la l\u00ednea de comandos. En este ejemplo, abriremos sendmail, y diremos que busque en la carta la direcci\u00f3n de destino.<\/p>\n

open(MAIL,”|\/usr\/lib\/sendmail -t”);<\/p>\n

Como se puede observar, es igual que una llamada a fichero, pero los s\u00edmbolos ‘>’ o ‘<‘ han sido sustituidos por un ‘|’ (tuber\u00eda). Esto indica que lo que hay detr\u00e1s de la tuber\u00eda es un ejecutable, y que lo que imprimamos en este FILEHANDLE se deber\u00e1 pasar como entrada a el programa ejecutable.<\/p>\n

Nota: No he comprobado si la operaci\u00f3n anterior termin\u00f3 con \u00e9xito, pero deber\u00edamos hacerlo. La manera m\u00e1s sencilla de hacerlo, es apoyarnos en que el comando open devuelve true cuando ha tenido \u00e9xito. Solo debemos hacer un OR entre el comando open y otro comando conociendo que ese comando ser\u00e1 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.<\/p>\n

open(MAIL,”|\/usr\/lib\/sendmail -t”) || die “La llamada a sendmail ha fallado”;<\/p>\n

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\u00ednea en blanco y el cuerpo del mensaje. Puedes echar un vistazo a un e-Mail que hayas recibido y comprobar las cabeceras. Describir\u00e9 abajo lo m\u00e1s importante. Los comentarios ser\u00e1n de ayuda.<\/p>\n

# Esta es la l\u00ednea ‘para’. Si tenemos el nombre y la direcci\u00f3n, escribiremos
\n# primero el nombre y luego la direcci\u00f3n entre <>
\nprint MAIL “To: $in{‘De’}n”;<\/p>\n

# Esta es la l\u00ednea ‘De’. Pondremos el mismo nombre en la l\u00ednea ‘De’ y en la ‘para’
\n# Recuerda que no hay seguridad comprobando el email, por ello estas l\u00edneas
\n# pueden ser falsificadas. NO FALSIFIQUES EL EMAIL, no es divertido y en algunos lugares
\n# es un delito.
\nprint MAIL “From: $in{De}n”;<\/p>\n

# Esta es la l\u00ednea ‘contestar a’. Esta l\u00ednea se incluye debido a que algunos programas
\n# son bastante tontos y no siempre responden a la l\u00ednea ‘De’.
\n# Al menos respetar\u00e1n esta l\u00ednea.
\nprint MAIL “Reply-To: $in{De}n”;<\/p>\n

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

print MAIL “X-mailer: Mail.pl, a cgi-bin script at http:\/\/www.ctv.es\/users\/jperez\/www\/tutor\/ \/index.htmln”;
\nprint MAIL “X-Remote-Host: $ENV{‘REMOTE_HOST’} ($ENV{‘REMOTE_ADDR’})n”;
\nprint MAIL “X-Remote-User: $ENV{‘REMOTE_USER’}n”;
\nprint MAIL “X-disclaimer: La l\u00ednea De: puede estar falsificada “;
\nprint MAIL “No confiar en un 100% sobre la integridad de este mail. “;
\nprint MAIL “No somos responsables de este correo de ninguna maneran”;
\nif ($in{xurl} ne “”) {
\nprint MAIL “X-URL: $in{xurl}n”;
\n}<\/p>\n

# Finalmente escribimos la famosa l\u00ednea del asunto.
\n# Presatr atenci\u00f3n en la segunda nueva l\u00ednea. Esta es la l\u00ednea
\n# que va a separar el encabezado del cuerpo del mensaje.
\nprint MAIL “Subject: $in{subject} (WWW generated email)nn”;<\/p>\n

# Ahora vamos a escribir elcuerpo del mensaje.
\nprint MAIL $in{‘body’};<\/p>\n

Solo quedan dos cosas. Primero debemos cerrar la conexi\u00f3n con sendmail. Segundo debemos imprimir una p\u00e1gina ense\u00f1ando al usuario la carta que env\u00eda.<\/p>\n

Para cerrar la conexi\u00f3n, usaremos el comando close, justo como en cualquier otro manejador:<\/p>\n

close(MAIL);<\/p>\n

Imprimir la respuesta no es diferente a las otras p\u00e1ginas generadas din\u00e1micamente que ya hemos creado anteriormente. Deberemos dividir el campo TEXTAREA en l\u00edneas 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\u00edneas. Con ello se consigue el poder hacer los p\u00e1rrafos de manera m\u00e1s clara, pero el beneficio de hacerlo es cuestionable.<\/p>\n

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

foreach $l (split(‘n’,$in{‘body’})) {
\nprint “$l<BR>n”;
\n}<\/p>\n

Como se puede ver separa la variable $in{‘body’} en partes cada nueva l\u00ednea, y la imprime seguida de un <BR>.<\/p>\n","protected":false},"excerpt":{"rendered":"

programando un CGI para enviar mail<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/pages\/10603"}],"collection":[{"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/comments?post=10603"}],"version-history":[{"count":0,"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/pages\/10603\/revisions"}],"wp:attachment":[{"href":"http:\/\/localhost\/datacraft2023\/wp-json\/wp\/v2\/media?parent=10603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}