Nell'ultimo articolo di questa serie abbiamo scritto la nostra prima
form e il nostro primo programma di interfaccia con il Web, usando il
protocollo CGI.
Ora proviamo a scrivere qualcosa di più impegnativo e, allo
stesso tempo, cerchiamo di riutilizzare quanto è stato già
fatto nel campo dei programmi CGI.
Proviamo a scrivere un programma
che legga le informazioni inserite in una form e le spedisca al
Webmaster del nostro server.
Uno scopo secondario di questo articolo è quello di mostrare che
al mondo esistono moduli già fatti e che possiamo riutilizzarli
per rendere più veloce la scrittura del nostro programma,
aumentarne la leggibilità, diminuirne il numero di linee e
quindi il numero dei possibili bugs (secondo la sperimentata filosofia
che meno si scrive e meno si sbaglia :-)
Cominciamo con il comporre una pagina HTML: la nostra form per la richiesta dei dati:
<html> <head> <title>Messaggio al webmaster del Mio Server</title> </head> <body> <h2>Messaggio al webmaster del Mio Server</h2> <hr> Se si desidera richiedere nuovi servizi, suggerire modifiche o dare dei pareri sull'impostazione del Server WEB, non esitare ad inserire un messaggio nell'apposita casella. <p> Assicurati di aver riempito <b>TUTTI</b> i campi. <FORM METHOD="POST" ACTION="/cgi-bin/posta_in_arrivo"> <PRE>Cognome e Nome: <INPUT NAME="name" size=30><p> <PRE>Indirizzo di E-mail: <INPUT NAME="email" size=30><p> <PRE>Oggetto del commento: <INPUT NAME="object" size=30> <INPUT NAME="recipient" VALUE="root" TYPE="hidden"> <P>Testo:<br> <TEXTAREA NAME="content" ROWS=6 COLS=60></TEXTAREA> <P> <INPUT TYPE="submit" VALUE="spedisci"> (per spedire il tuo messaggio)<br> <INPUT TYPE="reset" VALUE="cancella"> (per ripulire la pagina). <hr> </form> </body> </html>Questa volta abbiamo usato anche un campo nascosto: recipient, che contiene il nome dell'utente che dovrà ricevere la nostra mail.
In questo caso avremmo potuto codificare il nome del destinatario nel nostro script, ma probabilmente un file HTML è più facile da manutenere di un programma per chi non è un programmatore, come probabilmente non lo sarà il nostro cliente-tipo.
Salviamo questa pagina come
/var/httpd/htdocs/email.html.
A questo punto dobbiamo scrivere il programma posta_in_arrivo, come specificato nella form, e salvarlo sotto
/var/httpd/cgi-bin/
Come mio solito scriverò questo programma in Perl, usando il modulo CGI::Form.
Questo modulo non fa parte della distribuzione base del Perl 5, ma va prelevato da uno dei siti del CPAN (Comprehensive Perl Archive Network).
Proviamo subito questo modulo, scrivendo un programmino che legga la form e ci mostri quali variabili il server passa al nostro programma e come le informazioni immesse nella pagina arrivano a noi:
#!/usr/bin/perl use CGI::Form; $query = new CGI::Form; print $query->header; print $query->FmtRequest();Questo è proprio ciò che si definisce un ``programmino''!
Per provarlo salviamolo come
/var/httpd/cgi-bin/posta_in_arrivo
poi, come root, diamo il comando:
$ chmod a+x posta_in_arrivo
ATTENZIONE: i programmi CGI di solito vengono eseguiti come utente nobody, quindi non è sufficiente assegnare permessi di esecuzione al solo possessore del file!
A questo punto potete eseguire una prova: se state lavorando sulla stessa macchina su cui avete il server Web leggete il documento all'indirizzo:
http://localhost/email.html
riempite i campi e premete il pulsante spedisci. Il vostro server vi risponderà con qualcosa del tipo:
content = 'Messaggio per il Webmaster.' email = 'lac0658@iperbole.bologna.it' name = 'Santagata Nando' recipient = 'root' subject = 'Hello!'
AUTH_TYPE = undefined CONTENT_LENGTH = '128' CONTENT_TYPE = 'application/x-www-form-urlencoded' GATEWAY_INTERFACE = 'CGI/1.1' HTTP_ACCEPT = 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*' HTTP_REFERER = 'http://localhost/email.html' HTTP_USER_AGENT = 'Mozilla/2.0b5 (X11; I; Linux 1.2.13 i486)' PATH_INFO = undefined PATH_TRANSLATED = undefined QUERY_STRING = 'name=Santagata+Nando&email=lac0658@iperbole.bologna.it&subject=Errori+vari&recipient=root&content=Ci+sono+alcuni+piccoli+errori.' REMOTE_ADDR = '127.0.0.1' REMOTE_HOST = 'localhost' REMOTE_IDENT = undefined REMOTE_USER = undefined REQUEST_METHOD = 'POST' SCRIPT_NAME = '/cgi-bin/posta_in_arrivo' SERVER_NAME = 'localhost' SERVER_PORT = '80' SERVER_PROTOCOL = 'HTTP/1.0' SERVER_SOFTWARE = 'NCSA/1.3' URI = http://localhost:80/cgi-bin/posta_in_arrivo
Come vedete ci sono alcune informazioni che potrebbero esserci utili, ad esempio il REMOTE_ADDR o il HTTP_USER_AGENT (utile quest'ultimo se vogliamo cercare di massimizzare le prestazioni del singolo client).
Procediamo: abbiamo visto che il nostro programma riesce a passarci
tutte le informazioni che sono state immesse. Ora non ci resta che
comporre una mail.
Riscriviamo così il nostro programma:
#!/usr/bin/perl use CGI::Form; $query = new CGI::Form; $email = $query->param('email'); $recipient = $query->param('recipient'); $name = $query->param('name'); $object = $query->param('object'); $content = $query->param('content'); open (SENDMAIL, "|/usr/bin/sendmail -oi -t") || die "Non posso usare sendmail: $!"; print SENDMAIL <<QQ_EOF_QQ; To: $recipient From: $name <$email> Cc: $name <$email> Subject: $object Commento da parte di $name all'indirizzo $email: $content QQ_EOF_QQ close SENDMAIL; if ($?){ warn "sendmail non e` stato eseguito correttamente: $?" } print $query->header; print $query->start_html(-title => 'Grazie del commento', -BGCOLOR => "#00A0A0"); print <<EOF; <h3>Ti ringraziamo per la collaborazione</h3> <p> Il tuo messaggio è stato recapitato al Webmaster e una copia ti è stata spedita per conoscenza. EOF print $query->end_html;Salviamo questo programma sempre con il nome:
/var/httpd/cgi-bin/posta_in_arrivo
e diamogli permessi di esecuzione per tutti gli utenti.
Quando questo programma verrà eseguito spedirà due mail:
una al Webmaster (in questo caso `root') e una per conoscenza
all'utente che ha scritto il commento.
Analizziamo questo programma. La linea:
$query = new CGI::Form;crea un oggetto di tipo CGI::Form e contemporaneamente legge il contenuto della form, sia che il metodo associato fosse il GET, sia che fosse il POST.
Le righe seguenti:
$email = $query->param('email'); $recipient = $query->param('recipient'); $name = $query->param('name'); $object = $query->param('object'); $content = $query->param('content');scrivono i valori dei campi all'interno di alcune variabili.
open (SENDMAIL, "|/usr/bin/sendmail -oi -t") || die "Non posso usare sendmail: $!";in questo modo viene aperta una pipe sulla quale si potrà scrivere come se fosse un file qualsiasi.
Non ci resta ora che avvertire l'utente che tutto è andato a buon fine. La riga:
print $query->header;si limita a sputare fuori la formula magica:
print "Content-type: text/html\n\n";
che rende noto al nostro server che stiamo scrivendo una pagina HTML.
La riga:
print $query->start_html(-title => 'Grazie del commento', -BGCOLOR => "#00A0A0");compone la testata della pagina, con il titolo e l'indicazione del colore da assegnare allo sfondo, mentre la riga:
print $query->end_html;emette un:
</body></html>
A rileggerci alla prossima. Nel frattempo per dubbi, congratulazioni, correzioni, insulti & altro scrivete a Nando Santagata.