[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]

167. Server Web-CGI

In precedenza, nei capitoli 95 e 166, è stato descritto il servizio HTTP, la configurazione di Apache e l'utilizzo di un client in grado di accedere a tale servizio. In questo capitolo si intende vedere in che modo si può organizzare il proprio server HTTP in modo da renderlo interattivo attraverso l'uso dei programmi CGI.

167.1 HTTP e CGI

HTTP (HyperText Transfer Protocol) è un protocollo client-server progettato per gestire documenti ipertestuali e per permettere l'interazione con programmi, detti gateway, attraverso le specifiche CGI (Common Gateway Interface).

L'interfaccia CGI permette quindi di realizzare programmi che interagiscono con gli utenti attraverso il protocollo HTTP. La figura 167.1 illustra il meccanismo.


Figura 167.1: Schema del collegamento fisico e ideale tra le varie parti di una connessione HTTP-CGI.

I programmi gateway, detti anche cgi-bin o più semplicemente CGI, possono essere realizzati con qualunque linguaggio, purché siano in grado di interagire attraverso le specifiche del protocollo CGI.

167.2 URI e query

Nella sezione 95.3.1 è stato descritto in modo generale l'utilizzo degli indirizzi URI. Vale la pena di richiamare brevemente quei concetti per aggiungere ciò che riguarda in particolare la gestione interattiva che si vuole descrivere in questo capitolo. Il formato generale di un URI potrebbe essere definito secondo lo schema seguente:

<protocollo><indirizzo-della-risorsa><dati-aggiuntivi>

Alcuni tipi di protocolli sono in grado di gestire dei dati aggiuntivi in coda all'indirizzo della risorsa. Nel caso del protocollo HTTP combinato con CGI, può trattarsi di richieste o di percorsi aggiuntivi.

167.2.1 Stringhe di richiesta

<protocollo><indirizzo-della-risorsa>?<richiesta>

Quando un URI comprende anche una stringa di richiesta (query), questa viene distinta dall'indirizzo della risorsa attraverso un punto interrogativo. *1*

L'utilizzo di una stringa di richiesta presume che la risorsa sia un programma in grado di utilizzare l'informazione contenuta in tale stringa. Segue un esempio banale di un URI contenente una richiesta.

http://www.brot.dg/cgi-bin/saluti.pl?buongiorno

167.2.2 Percorsi aggiuntivi

<protocollo><indirizzo-della-risorsa><percorso-aggiuntivo>

Quando l'indirizzo della risorsa di un URI fa riferimento a un programma, questo può ricevere un'informazione aggiuntiva legata a un file o una directory particolare. Si ottiene questo aggiungendo l'indicazione del percorso che identifica questo file o questa directory. Segue un esempio banale di un URI, completo dell'indicazione di un percorso.

http://www.brot.dg/cgi-bin/elabora.pl/archivio.doc

167.2.3 Codifica

Un problema che non è stato descritto in precedenza è il tipo di codifica utilizzabile per la scrittura di indirizzi URI. Si possono utilizzare solo i simboli della codifica ASCII tradizionale a 7 bit (i codici inferiori o uguali a 127) e tra questi, gran parte dei simboli di punteggiatura sono esclusi. In pratica, sono valide le lettere dell'alfabeto (maiuscole e minuscole), le cifre numeriche e i simboli: at (@), asterisco (*), sottolineato (_), trattino (-) e il punto (.). Gli altri non possono essere usati o hanno significati particolari (basta pensare alle barre oblique che servono per separare il nome del protocollo dall'indirizzo del dominio e anche per separare le sottodirectory).

Quando un simbolo di quelli non utilizzabili deve essere indicato ugualmente da qualche parte dell'URI, facendogli perdere il significato speciale che questo potrebbe avere altrimenti, si può convertire utilizzando la notazione %hh. La sigla hh rappresenta una coppia di cifre esadecimali. A questa regola fa eccezione lo spazio che viene codificato normalmente con il segno +, ma non in tutte le occasioni.

Generalmente, per gli indirizzi URI normali non c'è la necessità di preoccuparsi di questo problema, a parte il caso della tilde (~), utilizzata frequentemente nei percorsi che fanno riferimento a pagine HTML personali di un determinato utente di un certo elaboratore. Per intendere di cosa si parla, basta vedere l'esempio seguente:

http://www.brot.dg/~daniele/index.html

Spesso, i programmi client e server HTTP sono in grado di accettare eccezionalmente questo tipo di indicazione senza pretendere la notazione corretta che dovrebbe essere quella seguente:

http://www.brot.dg/%7Edaniele/index.html

Quindi, se di solito non esiste questa preoccupazione, il problema dell'utilizzo di simboli particolari riguarda prettamente la costruzione delle richieste, come si vedrà meglio in seguito.

La tabella 167.1 mostra l'elenco di alcune corrispondenze tra simboli particolari e la codifica alternativa utilizzabile negli URI.

Carattere Codifica
% %25
& %26
+ %2B
/ %2F
= %3D
~ %7E

Tabella 167.1: Alcune corrispondenze tra simboli particolari e codifica alternativa utilizzabile negli URI.

167.2.4 Collocazione effettiva

Il server HTTP mostra ai client solo una parte dei dati contenuti all'interno del proprio sistema, e ciò attraverso una sorta di astrazione per cui, per esempio, http://www.brot.dg/ciao.html non è il file ciao.html che si trova nella directory radice del filesystem del nodo www.brot.dg.

L'organizzazione e l'accessibilità dei dati attraverso il protocollo HTTP può essere gestita in vario modo. Apache (il server più comune) utilizza per questo il file etc/httpd/conf/srm.conf in cui vanno indicate, tra le altre, le direttive seguenti.

DocumentRoot <directory-root-html>

Rappresenta la directory da cui si possono diramare i documenti HTML. Se per esempio si trattasse della riga seguente,

DocumentRoot /home/httpd/html

e un client volesse accedere al documento http://www.brot.dg/ciao.html, il file restituito effettivamente sarebbe /home/httpd/html/ciao.html.

Alias <directory-fasulla> <directory-reale>

Questo tipo di direttiva, che può essere ripetuta, permette di definire delle directory in posizioni diverse da quelle reali. La directory fasulla fa riferimento a una directory indicata nell'indirizzo richiesto e quella reale indica la directory effettiva nel filesystem. Per esempio,

Alias /icons/ /home/httpd/icons/

fa in modo che l'indirizzo http://www.brot.dg/icons/ faccia in realtà riferimento alla directory /home/httpd/icons/ e non alla directory icons/ discendente da DocumentRoot.

ScriptAlias <directory-fasulla> <directory-reale>

Funziona come la direttiva Alias, ma si riferisce ai programmi CGI. Per esempio,

ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/

fa in modo che l'indirizzo http://www.brot.dg/cgi-bin/ faccia in realtà riferimento alla directory /home/httpd/cgi-bin/ e non alla directory /cgi-bin/ discendente da DocumentRoot.

Questa indicazione è particolarmente importante per lo scopo di questo capitolo: stabilisce che tutto ciò che discende da questa directory deve essere trattato come un programma gateway, per cui, il riferimento a un file contenuto qui significa mettere in esecuzione tale file.

167.3 Protocollo HTTP

Il funzionamento del protocollo HTTP è molto semplice. L'utilizzo di un servizio HTTP si compone di una serie di transazioni, ognuna delle quali si articola in queste fasi:

  1. apertura della connessione;

  2. invio da parte del client di una richiesta;

  3. risposta da parte del server;

  4. chiusura della connessione.

In questo modo, il server non deve tenere traccia delle transazioni che iniziano e finiscono ogni volta che un utente compie un'azione attraverso il suo client.

La richiesta inviata dal client deve contenere il metodo (i più comuni sono GET e POST), l'indicazione della risorsa cui si vuole accedere, la versione del protocollo, ed eventualmente l'indicazione dei tipi di dati che possono essere gestiti dal client (si parla in questi casi di tipi MIME). Naturalmente sono possibili richieste più ricche di informazioni.

Nome Descrizione
GET Recupera l'informazione identificata dall'URI specificato.
HEAD Recupera le informazioni sul documento, senza ottenere il documento in allegato.
PUT Richiede che l'informazione sia memorizzata nell'URI specificato.
POST Fornisce al server dati aggiuntivi in riferimento all'URI specificato.
DELETE Richiede di eliminare la risorsa specificata.
LINK Stabilisce una collegamento con la risorsa indicata.
UNLINK Elimina un collegamento tra risorse.

Tabella 167.2: Alcuni metodi di comunicazione per le richieste di un client.

La risposta del server HTTP è costituita da un'intestazione che, tra le altre cose, specifica il modo in cui l'informazione allegata deve essere interpretata. È importante comprendere subito che l'intestazione viene staccata dall'inizio dell'informazione allegata attraverso un riga vuota, composta dalla sequenza <CR><LF>.

167.3.1 Analisi di una connessione HTTP

Per comprendere in pratica il funzionamento di una connessione HTTP, si può utilizzare il programma telnet al posto di un navigatore normale. Si suppone di poter accedere al nodo www.brot.dg nel quale è stato installato Apache con successo. Dal server verrà prelevato il file index.html che si trova all'interno della directory DocumentRoot.

telnet www.brot.dg http[Invio]

telnet risponde e si mette in attesa di ricevere il messaggio da inviare al server.

Trying 192.168.1.1...
Connected to www.brot.dg.
Escape character is '^]'.

Si deve iniziare a scrivere, cominciando con una riga contenente il metodo, la risorsa e la versione del protocollo, continuando con una riga contenente le possibilità di visualizzazione del client (i tipi MIME).

GET /index.html HTTP/1.0[Invio]

Accept: text/html[Invio]

[Invio]

Appena si invia una riga vuota, il server intende che la richiesta sia terminata e risponde.

HTTP/1.1 200 OK
Date: Tue, 27 Jan 1998 17:44:46 GMT
Server: Apache/1.2.4
Last-Modified: Tue, 30 Dec 1997 21:07:24 GMT
ETag: "6b003-792-34a9628c"
Content-Length: 1938
Accept-Ranges: bytes
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
 <HEAD>
  <TITLE>Test Page for Linux's Apache Installation</TITLE>
 </HEAD>
<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
 <BODY
  BGCOLOR="#FFFFFF"
  TEXT="#000000"
  LINK="#0000FF"
  VLINK="#000080"
  ALINK="#FF0000"
 >
  <H1 ALIGN="CENTER">It Worked!</H1>
  <P>
  If you can see this, it means that the installation of the
  <A
   HREF="http://www.apache.org/"
  >Apache</A>
  software on this Linux system was successful. You may now add content to
  this directory and replace this page.
  </P>
...
...
 </BODY>
</HTML>
Connection closed by foreign host.         

Come già accennato, il messaggio restituito dal server è composto da un'intestazione in cui l'informazione più importante è il tipo di messaggio allegato, cioè in questo caso Content-Type: text/html, seguita da una riga vuota, e quindi dall'oggetto richiesto, cioè il file index.html.

Al termine della ricezione dell'oggetto richiesto, la connessione ha termine. Lo si può osservare dal messaggio dato da telnet: Connection closed by foreign host.

Il lavoro del client è tutto qui: inviare richieste al server, ricevere le risposte e gestire i dati, possibilmente visualizzandoli o mettendo comunque l'utente in grado di fruirne.

167.3.2 Tipi MIME

MIME è una codifica standard per definire il trasferimento di documenti multimediali attraverso la rete. L'acronimo sta per Multipurpose Internet Mail Extentions e la sua origine è appunto legata ai trasferimenti di dati allegati ai messaggi di posta, come il nome lascia intendere.

Il protocollo HTTP utilizza lo stesso standard, e con questo il server informa il client del tipo di oggetto che gli viene inviato. Nello stesso modo, il client, all'atto della richiesta di una risorsa, informa il server dei tipi MIME che è in grado di gestire.

Il server, per poter comunicare il tipo MIME al client, deve avere un modo per riconoscere la natura degli oggetti che costituiscono le risorse accessibili. Questo modo è dato dall'estensione, per cui, la stessa scelta dell'estensione per i file accessibili attraverso il protocollo HTTP è praticamente obbligatoria, ovvero, dipende dalla configurazione dei tipi MIME.

Tipo MIME Estensioni Descrizione
application/postscript ps eps PostScript.
application/rtf rtf Rich Text Format.
application/x-tex tex Documento TeX/LaTeX.
audio/basic au snd File audio.
audio/x-wav wav File audio.
image/gif gif Immagine GIF.
image/jpeg jpeg jpg Immagine JPEG.
image/tiff tiff tif Immagine TIFF.
image/x-xwindowdump xwd Immagine X Window Dump.
text/html html htm Testo formattato in HTML.
text/plain txt Testo puro.
video/mpeg mpeg mpg mpe Animazione MPEG.
video/quicktime qt mov Animazione Quicktime.

Tabella 167.3: Alcuni tipi MIME con le possibili estensioni.

167.3.3 Campi di richiesta

Come si è visto dagli esempi mostrati precedentemente, la richiesta fatta dal client è composta da una prima riga in cui si dichiara il tipo, la risorsa desiderata e la versione del protocollo.

GET /index.html HTTP/1.0

Di seguito vengono indicati una serie di campi, più o meno facoltativi. Questi campi sono costituiti da un nome seguito da due punti (:), da uno spazio e dall'informazione che gli si vuole abbinare.

167.3.3.1 Campo Accept

Una o più righe contenenti un campo Accept possono essere incluse per indicare i tipi MIME che il client è in grado di gestire (cioè di ricevere). Se non viene indicato alcun campo Accept, si intende che siano accettati almeno i tipi text/plain e text/html.

I tipi MIME sono organizzati attraverso due parole chiave separate da una barra obliqua. In pratica si distingue un tipo e un sottotipo MIME. È possibile indicare un gruppo di tipi MIME mettendo un asterisco al posto di una o di entrambe le parole chiave, in modo da selezionare tutto il gruppo relativo. Per esempio,

Accept: */*

rappresenta tutti i tipi MIME;

Accept: text/*

rappresenta tutti i sottotipi MIME che appartengono al tipo text; mentre

Accept: audio/basic

rappresenta un tipo e un sottotipo MIME particolare.

167.3.3.2 Campo User-Agent

Il campo User-Agent permette di informare il server sul nome e sulla versione dell'applicativo particolare che svolge la funzione di client. Per convenzione, il nome di questo è seguito da una barra obliqua e dal numero della versione. Tutto quello che dovesse seguire sono solo informazioni addizionali per le quali non è stabilita una forma precisa. Per esempio, nel caso di Netscape, si potrebbe avere un'indicazione del tipo seguente:

User-Agent: Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i586)

167.3.4 Campi di risposta

La risposta del server a una richiesta del client si compone di un'intestazione seguita eventualmente da un allegato, che costituisce la risorsa a cui il client voleva accedere. L'intestazione è separata dall'allegato da una riga vuota.

La prima riga è costituita dal codice di stato della risposta. Nella migliore delle ipotesi dovrebbe presentarsi come nell'esempio seguente:

HTTP/1.0 200 OK

Il resto dell'intestazione è composto da campi, simili a quelli utilizzati per le richieste dei client.

Codice Descrizione
200 OK
201 Creato.
202 Accettato.
204 Nessun contenuto.
300 Scelte multiple.
301 Spostato in modo permanente.
302 Spostato temporaneamente.
304 Non modificato.
400 Richiesta errata.
401 Non autorizzato.
403 Proibito.
404 Non trovato.
500 Errore interno del server.
501 Servizio non realizzato (non disponibile).
502 Gateway errato.
503 Servizio non disponibile.

Tabella 167.4: Alcuni codici di stato utilizzati più frequentemente.

167.3.4.1 Campo Allow

Il campo Allow viene utilizzato dal server per informare il client dei metodi che possono essere utilizzati. Viene restituita tale informazione quando il client tenta di utilizzare un metodo di richiesta che il server non è in grado di gestire. Segue un esempio.

Allow: GET, HEAD, POST

167.3.4.2 Campo Content-Length

Il campo Content-Length indica al client la dimensione (in byte) dell'allegato. Se viene utilizzato il metodo HEAD, con cui non viene restituito alcun allegato, permette di conoscere in anticipo la dimensione della risorsa.

Content-Length: 1938

167.3.4.3 Content-Type

Il campo Content-Type indica al client il tipo MIME a cui appartiene la risorsa (allegata o meno). Segue l'esempio più comune.

Content-Type: text/html

167.4 Input dell'utente

Il tipo di comunicazione che avviene tra client e server, descritta nelle sezioni precedenti, è nascosta all'utente, il quale agisce attraverso la richiesta e l'invio di documenti HTML.

Si distinguono tre tipi di definizioni da inserire all'interno di documenti HTML che permettono all'utente di inserire dati (nel senso di input):

167.4.1 ISINDEX

Quando un documento HTML contiene il marcatore (o tag) ISINDEX, il programma client fa apparire, in corrispondenza di questo, una richiesta di inserimento di un testo. La figura 167.2 mostra ciò che potrebbe apparire con un comune navigatore.


Figura 167.2: L'effetto della presenza di un marcatore ISINDEX all'interno di un documento HTML.

Si tratta di una forma antiquata di interazione tra l'utente e il servizio HTTP, ma tuttora utile per comprendere i meccanismi più complessi che di fatto vengono utilizzati.

L'utente inserisce quello che vuole all'interno del campo che gli viene messo a disposizione e quando lo sottopone (di solito si tratta di premere il tasto [Invio]), il programma client (cioè il navigatore) converte i caratteri che necessitano di conversione, quindi invia una richiesta GET per lo stesso documento, seguito da una stringa di richiesta (preceduta dal solito punto interrogativo) ottenuta da quanto l'utente aveva inserito.

167.4.2 ISMAP

Un marcatore di riferimento a un file di immagine può contenere l'attributo ISMAP: <IMG SRC="..." ISMAP>. Se il marcatore dell'immagine è contenuto a sua volta in un riferimento a una risorsa, attraverso l'uso del mouse, facendo clic in una posizione qualunque dell'immagine che appare, si inviano le coordinate relative all'indirizzo indicato.

L'esempio seguente mostra il riferimento a un'immagine, racchiuso all'interno di un riferimento a un programma CGI in grado di gestire le coordinate.

<A HREF="http://www.brot.dg/cgi-bin/coordinate.pl">
	<IMG SRC="http://www.brot.dg/immagini/punta.gif ISMAP>
</A>

Facendo un clic sull'immagine punta.gif mostrata dal programma client all'utente, vengono inviate le coordinate attraverso una richiesta GET all'indirizzo della risorsa coordinate.pl. Questo indirizzo risulterà essere seguito da una stringa di richiesta (preceduta dal punto interrogativo) composta da due numeri interi, staccati da una virgola, che rappresentano rispettivamente le coordinate x e y.

167.4.3 FORM

I moduli FORM nei documenti HTML sono il modo più complesso e completo per permettere a un utente di interagire con un servizio. A differenza di quanto visto in precedenza, si consente l'inserimento di molte informazioni che poi vengono trasmesse nella forma <nome>=<valore>. I dati inseriti attraverso i FORM possono essere trasmessi con una richiesta GET oppure POST, attraverso l'indicazione opportuna all'interno dello stesso documento HTML che contiene il modulo.

La descrizione di questi moduli FORM verrà fatta più avanti, dopo gli esempi che servono a mostrare i meccanismi elementari di comunicazione dati relativi a ISINDEX e ISMAP.

167.5 Primi approcci alla programmazione CGI

I programmi gateway, o CGI, vengono visti dai client come delle risorse normali. Alla chiamata, tali programmi restituiscono, attraverso il server, un documento HTML.

I programmi gateway generano questo output e lo emettono attraverso lo standard output che viene intercettato dal server che a sua volta lo completa inizialmente del codice di stato.

In pratica, un programma del genere riceve input in qualche modo attraverso il server, che a sua volta ha ricevuto una richiesta da un client, quindi restituisce un documento HTML preceduto da un'intestazione, ma senza la riga di stato.

167.5.1 Programma CGI banale

Un programma CGI banale, potrebbe essere quello che restituisce semplicemente un messaggio formattato in HTML, ogni volta che viene eseguito.

#!/bin/sh

echo "Content-type: text/html"
echo
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE>Programma CGI banale</TITLE>"
echo "</HEAD>"
echo "<BODY>"
echo "<H1>Programma CGI banale</H1>"
echo "<P>"
echo "Ciao Mondo!"
echo "</P>"
echo "</BODY>"
echo "</HTML>"

Supponendo di avere chiamato questo programma cgi-banale.sh, che sia stato reso eseguibile, e che si trovi nella directory definita attraverso la direttiva ScriptAlias come /cgi-bin/, si potrà accedervi aprendo l'URI http://.../cgi-bin/cgi-banale.sh. Se si fa una prova con il proprio elaboratore, che funge simultaneamente da client e da server, si potrebbe utilizzare l'URI http://localhost/cgi-bin/cgi-banale.sh.


Figura 167.3: Risultato per l'utente della richiesta di accedere all'URI che punta allo script elementare (cgi-banale.sh) che produce solo un output semplice senza interpretare alcun input.

167.5.2 Verifica della comunicazione tra server e programma gateway

Nelle sezioni precedenti si è visto in particolare il tipo di comunicazione che si instaura tra il programma client e il server, mentre la comunicazione tra il server e il programma gateway no.

Quando un client invia una richiesta di accedere a una risorsa che viene riconosciuta essere un programma gateway, il server esegue questo programma e lo standard output di questo viene inviato in risposta al client, con l'aggiunta del codice di risultato iniziale: la preparazione del resto dell'intestazione è a carico del programma gateway.

Quando il server esegue il programma gli può inviare alcuni dati: in forma di argomenti della riga di comando, utilizzando le variabili di ambiente e anche attraverso lo standard input. Dipende dalla modalità della richiesta fatta dal client il modo con cui il programma gateway riceverà i dati dal server.

È sufficiente realizzare uno script in grado di restituire tutti i dati che vengono forniti dal server al programma gateway per comprendere il meccanismo.

#!/bin/sh
#
# cgi-test.sh

echo "Content-type: text/html"
echo
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE>Test CGI</TITLE>"
echo "</HEAD>"
echo "<BODY>\n";
echo "<H1>Test CGI</H1>"
echo "<PRE>"
echo "N. argomenti = $#"
echo "Argomenti    = $*"
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 "SERVER_ADMIN = $SERVER_ADMIN"
echo "REQUEST_METHOD = $REQUEST_METHOD"
echo "HTTP_ACCEPT = $HTTP_ACCEPT"
echo "HTTP_USER_AGENT = $HTTP_USER_AGENT"
echo "HTTP_CONNECTION = $HTTP_CONNECTION"
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"
echo
echo "Standard input:"
cat
echo "</PRE>"
echo "</BODY>"
echo "</HTML>"


Figura 167.4: Richiamando lo script cgi-test.sh attraverso un URI, senza l'indicazione di alcuna stringa di richiesta, si ottiene lo stato delle variabili di ambiente fornite allo script stesso.

Eventualmente si può realizzare un altro programma, in Perl, che compie praticamente le stesse operazioni, ma in modo più preciso.

#!/usr/bin/perl
#
# cgi-test.pl

print "Content-type: text/html\n";
print "\n";
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Test CGI</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "<H1>Test CGI</H1>\n";
print "<PRE>\n";
print "N. argomenti = $#ARGV\n";
print "Argomenti    = @ARGV\n";
print "\n";

foreach $var_amb (keys %ENV) {
    print "$var_amb = $ENV{$var_amb}\n";
};

print "\n";
print "Standard input:";

while ( $riga = <STDIN> ) {
    print "$riga";
}

print "</PRE>\n";
print "</BODY>\n";
print "</HTML>\n";

167.5.3 Input elementari

Le forme più semplici attraverso cui un utente può dare un input a un programma gateway sono: i percorsi aggiuntivi, i marcatori ISINDEX e gli attributi ISMAP delle immagini.

Il percorso aggiuntivo, tra tutti, è il concetto più semplice, anche se raramente se ne incontra l'utilizzo. Si ottiene richiedendo un URI che punta a un programma gateway seguito immediatamente, e senza separazioni addizionali, da un percorso che indichi un file o una directory. Il programma gateway riceve questa informazione all'interno di variabili di ambiente.

Per verificarlo basta usare uno dei due script mostrati nella sezione precedente. Si può anche tentare di raggiungere un percorso che non esiste. Supponendo di indicare l'URI http://.../cgi-bin/cgi-test.sh/ciao/come/stai, lo script riceverà (e mostrerà) la variabile di ambiente PATH_INFO con il valore /ciao/come/stai, mentre la variabile PATH_TRANSLATED conterrà la (presunta) traduzione di quel percorso in un percorso reale, corrispondente probabilmente a <DocumentRoot>/ciao/come/stai. Sta quindi al programma (o allo script) gateway sapere cosa farsene di questa informazione.

Un'altra forma di input elementare, ormai in disuso, è il marcatore ISINDEX. Per comprendere di cosa si tratta basta modificare leggermente uno dei due script di analisi preparati nella sezione precedente. Viene mostrato il caso dello script di shell.

#!/bin/sh
#
# cgi-test2.sh

echo "Content-type: text/html"
echo
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE>Test CGI</TITLE>"
echo "</HEAD>"
echo "<BODY>"
echo "<H1>Test CGI</H1>"
echo "<PRE>"
echo "N. argomenti = $#"
echo "Argomenti    = $*"

...

#Viene inviato un marcatore ISINDEX.
echo "<ISINDEX>"

echo "</PRE>"
echo "</BODY>"
echo "</HTML>"

In corrispondenza del marcatore ISINDEX, il programma client mostrerà un campo modificabile dall'utente, come appare nella figura 167.2 già mostrata in precedenza. Per esempio, si può provare a scrivere la frase uno due tre, premere [Invio] e vedere cosa succede (si immagina che lo script si chiami cgi-test2.sh).

Gli spazi vengono trasformati con il segno + e il testo corrispondente viene accodato all'URI (dopo l'aggiunta di un punto interrogativo): http://.../cgi-bin/cgi-test2.sh?uno+due+tre. Per questo URI, completato della stringa codificata, il client esegue una richiesta GET.

Il programma gateway riceve questa informazione attraverso la variabile di ambiente QUERY_STRING, che conterrà uno+due+tre, e anche attraverso gli argomenti della riga di comando, dove le tre parole corrispondono ad altrettanti argomenti separati.

L'ultimo, tra i tipi di input descritti in questa sezione, è quello ottenuto attraverso l'attributo ISMAP delle immagini. Per comprendere di cosa si tratta, basta modificare leggermente uno dei due script di analisi preparati nella sezione precedente. Viene mostrato il caso dello script di shell.

#!/bin/sh
#
# cgi-test3.sh

echo "Content-type: text/html"
echo
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE>Test CGI</TITLE>"
echo "</HEAD>"
echo "<BODY>"
echo "<H1>Test CGI</H1>"
echo "<PRE>"
echo "N. argomenti = $#"
echo "Argomenti    = $*"

...

#Viene mostrata un'immagine con attributo ISMAP.
echo "<A HREF=\"/cgi-bin/cgi-test3.sh\">"
echo "    <IMG SRC=\"/test.jpg\" ISMAP>"
echo "</A>"

echo "</PRE>"
echo "</BODY>"
echo "</HTML>"

Per vedere funzionare questo esempio occorre anche un file di immagine, test.jpg, da collocare nella directory di inizio dei documenti HTML, ovvero DocumentRoot.

Basta fare un clic con il mouse, da qualche parte sull'immagine, perché il programma client calcoli le coordinate corrispondenti, espresse in pixel, e le attacchi in coda all'URI. Per esempio, l'URI http://.../cgi-bin/cgi-test3.sh?10,15 rappresenta un clic eseguito nel punto x=10, y=15.

Il programma (lo script) cgi-test3.sh riceve questa informazione attraverso la riga di comando e anche attraverso il contenuto della variabile QUERY_STRING.

167.6 Moduli FORM

Si è già accennato ai moduli FORM HTML. Fino a questo punto si sono viste tecniche elementari per permettere l'interazione tra l'utente e un servizio HTTP. In particolare, il campo ISINDEX è praticamente del tutto inutilizzato. La vera interazione avviene con modelli HTML complessi, basati sui moduli FORM. Un particolare da osservare, prima di affrontare questo nuovo argomento, è il fatto che tutti i tipi di interazione visti finora sono basati su richieste che utilizzano il metodo GET.

I moduli FORM servono a generare degli elementi di input, che permettono quindi all'utente di inserire un certo tipo di dati. L'input ottenuto in questo modo viene assemblato in coppie <nome>=<valore>. È poi compito del programma gateway disassemblare e interpretare tali informazioni.

I moduli FORM vengono generati dal programma client (cioè dal browser) in base alle direttive incontrate all'interno di un documento HTML. Ciò significa che l'apparenza di questi moduli può essere diversa a seconda del programma client utilizzato e del sistema operativo.

Il documento HTML contenente moduli di questo tipo, ovviamente, può essere stato predisposto nel server come file normale, oppure può essere generato dinamicamente da un programma gateway.

167.6.1 Dichiarazione

Un modulo di questo tipo viene dichiarato e delimitato dall'elemento FORM, all'interno di un documento HTML:

<FORM ...>
	...
	...
	...
</FORM>

Un documento HTML può contenere più FORM, purché non annidati. Il marcatore FORM di apertura può contenere degli attributi che ne definiscono il comportamento generale, mentre all'interno della zona definita dall'elemento FORM si possono inserire altri elementi di vario genere, il cui scopo è quello di permettere all'utente un tipo particolare di interazione.

167.6.2 Attributo ACTION

L'attributo ACTION dell'elemento FORM specifica l'URI a cui inviare i dati inseriti attraverso il modulo. Deve trattarsi evidentemente dell'indirizzo di un programma gateway in grado di gestirli. Intuitivamente si comprende che questo attributo non può mancare. L'esempio seguente mostra in che modo si possa inserire questo attributo.

<FORM ACTION="http://www.brot.dg/cgi-bin/mio_programma.pl ...>

167.6.3 Attributo METHOD

L'attributo METHOD dell'elemento FORM specifica il metodo della richiesta che deve essere fatta dal client. Utilizzando un modulo FORM sono disponibili due tipi: GET e POST. L'esempio seguente mostra una situazione in cui si definisce l'utilizzo del metodo POST.

<FORM ACTION="http://www.brot.dg/cgi-bin/mio_programma.pl METHOD="POST">

167.7 Elementi dell'ambiente FORM

All'interno dell'ambiente FORM, cioè della zona delimitata dai marcatori <FORM> e </FORM>, si può collocare sia testo normale che elementi specifici di questo ambiente. Si è ripetuto più volte che i dati inseriti attraverso questi elementi vengono assemblati in coppie <nome>=<valore>. Quello che manca da sapere è che tali coppie vengono unite successivamente attraverso il simbolo e-commerciale (&). Gli esempi proposti più avanti mostreranno meglio questo comportamento.

Esistono pochi tipi di elementi atti a permettere l'input all'interno dell'ambiente FORM. Questi cambiano il loro comportamento e l'apparenza a seconda degli attributi che gli vengono indicati. Il tipo di elemento più comune è INPUT.

<INPUT NAME=... TYPE=... ...>

Tutti gli elementi che permettono l'input hanno in comune l'attributo NAME che è obbligatorio. Le sezioni seguenti mostrano alcuni degli elementi utilizzabili in un modulo.

167.7.1 INPUT generico

Si tratta di un elemento che consente l'inserimento di testo normale su una sola riga. Questo elemento non richiede l'indicazione del tipo, attraverso l'attributo TYPE.

Attributi specifici

SIZE=n

Permette di definire la dimensione in caratteri del campo che si vuole visualizzare.

MAXLENGTH=n

Permette di stabilire un limite massimo alla dimensione, in caratteri, del testo che si può immettere.

VALUE=x

Permette di definire un valore predefinito che appaia già all'interno del campo.

Esempi

Inserisci il colore: <INPUT NAME="colore" SIZE=20 VALUE="giallo">

Visualizza un campo di 20 caratteri all'interno del quale l'utente deve scrivere il nome di un colore. Nel campo appare già la scritta giallo che può essere modificata o cancellata a piacimento.

167.7.2 INPUT TYPE=password

Si tratta di un elemento che consente la scrittura di testo normale nascondendone l'inserimento, come avviene di solito quando si introducono le password.

Dal momento che, a parte l'oscuramento dell'input, il funzionamento è uguale a quello dei campi di input normali, si possono utilizzare anche gli stessi tipi di attributi.

Esempi

Inserisci la password: <INPUT TYPE=password NAME="password-utente" SIZE=20>

Visualizza un campo di 20 caratteri all'interno del quale l'utente deve inserire la password richiesta.

167.7.3 INPUT TYPE=checkbox

Si tratta di un elemento che visualizza una casellina da barrare. Queste caselline appaiono senza selezione in modo predefinito, a meno che venga utilizzato l'attributo CHECKED. Se la casellina risulta selezionata, viene generata la coppia <nome>=<valore> corrispondente, altrimenti no.

Attributi specifici

VALUE=x

Permette di definire un valore (o una stringa) da restituire nel caso in cui la casellina sia selezionata. Questo attributo è essenziale.

CHECKED

Questo attributo vale in quanto presente o meno. Se viene inserito nell'elemento, la casellina apparirà inizialmente selezionata.

Esempi

Barrare la casella se si desidera ricevere propaganda:
<INPUT TYPE=checkbox NAME="propaganda" VALUE="SI" CHECKED >

Visualizza una casellina già barrata inizialmente. Se viene lasciata così, selezionata, questo elemento genererà la coppia propaganda=SI.

167.7.4 INPUT TYPE=radio

Si tratta di un elemento che permette la selezione esclusiva di un pulsante all'interno di un gruppo. In pratica, selezionandone uno, si deselezionano gli altri.

Rispetto agli elementi visti in precedenza, questo richiede la presenza di più elementi dello stesso tipo, altrimenti non ci sarebbe da scegliere. Il collegamento che stabilisce che i pulsanti appartengono allo stesso gruppo viene definito dal nome che rimane uguale.

Attributi specifici

VALUE=x

Permette di definire un valore (o una stringa) da restituire nel caso in cui il bottone risulti selezionato. Questo attributo è essenziale.

CHECKED

Questo attributo vale in quanto presente o meno. Se viene inserito nell'elemento, il bottone apparirà inizialmente selezionato.

Esempi

Selezionare il contenitore dell'elaboratore:
<INPUT TYPE=radio NAME="case" VALUE="desktop" CHECKED >
<INPUT TYPE=radio NAME="case" VALUE="tower" >
<INPUT TYPE=radio NAME="case" VALUE="minitower" >

Visualizza tre pulsanti, di cui il primo già selezionato, per la scelta di un tipo di contenitore. I tre bottoni sono collegati insieme perché hanno lo stesso valore associato all'attributo NAME.

167.7.5 INPUT TYPE=submit

Questo tipo di elemento visualizza un tasto contenente un'etichetta, e selezionandolo si ottiene l'invio dei dati contenuti nel modulo in cui si trova. L'etichetta che appare sul pulsante in modo predefinito dipende dal client, e potrebbe trattarsi di Submit o qualcosa del genere.

Questo elemento è diverso dagli altri in quanto non è previsto l'uso dell'attributo NAME. Infatti non viene generato alcun dato da questo, ma solo l'invio dei dati del FORM.

Attributi specifici

SRC=<uri>

Permette di indicare l'URI di un'immagine da utilizzare come pulsante.

VALUE=x

Permette di indicare un'etichetta alternativa a quella che verrebbe messa automaticamente dal programma client.

Esempi

<INPUT TYPE=submit VALUE="Invia la richiesta" >

Visualizza un tasto sul quale appare la scritta Invia la richiesta. Selezionandolo viene inviato il contenuto del modulo.

167.7.6 INPUT TYPE=image

Si tratta di una sorta di tasto di invio (submit) che in più aggiunge le coordinate in cui si trovava il puntatore nel momento del clic. In un certo senso assomiglia anche all'elemento ISMAP descritto prima di affrontare i FORM.

Attributi specifici

SRC=<uri>

Permette di indicare l'URI dell'immagine da utilizzare come base. Questo attributo è obbligatorio data la natura dell'elemento.

Esempi

<INPUT TYPE=image NAME="immagine" SRC="/immagine.jpg" >

Visualizza l'immagine immagine.jpg e se viene fatto un clic con il puntatore del mouse sulla sua superficie, vengono inviati i dati del modulo, e assieme a questi anche le coordinate relative all'immagine.

167.7.7 INPUT TYPE=hidden

Questo tipo di elemento, a prima vista, non ha alcun senso: permette di inserire dei campi nascosti, cosa che genererà una coppia <nome>=<valore> fissa.

Si era detto, all'inizio di questo capitolo, che il protocollo HTTP non ha alcun controllo sullo stato delle transazioni, o meglio, ogni richiesta si conclude con una risposta. In questo modo, è compito del programma gateway mantenere il filo delle operazioni che si stanno svolgendo. Una delle tecniche con cui è possibile ottenere questo risultato è quella di restituire un modello contenente le informazioni già inserite con quelli precedenti.

Ci sono anche altre situazioni in cui i dati nascosti e predefiniti sono utili, ma per il momento è sufficiente tenere a mente che esiste la possibilità.

Attributi specifici

VALUE=x

Definisce il valore o la stringa nascosti. Questo argomento è obbligatorio per questo tipo di elemento.

Esempi

<INPUT TYPE=hidden NAME="nominativo" VALUE="Tizio" >

Fa in modo che il modulo contenga anche la coppia nominativo=Tizio che altrimenti, si suppone, renderebbe inutilizzabili gli altri dati inseriti dall'utente.

167.7.8 TEXTAREA

Questo elemento permette all'utente di inserire un testo su più righe. L'interruzione di riga, in questo caso, è fatta utilizzando la sequenza <CR><LF>. Questo particolare va tenuto presente in fase di programmazione, dal momento che gli ambienti Unix, e GNU/Linux in particolare, utilizzano l'interruzione di riga rappresentata con il solo carattere <LF>.

Attributi specifici

ROWS=n

Stabilisce il numero di righe dell'area di inserimento.

COLS=n

Stabilisce il numero di colonne dell'area di inserimento.

Esempi

<TEXTAREA NAME="messaggio" ROWS=7 COLS=40 >
CIAO!
</TEXTAREA>

Visualizza un'area per l'inserimento di testo su più righe. L'area visibile ha la dimensione di 7 righe per 40 colonne e contiene già il testo CIAO! che può essere modificato o sostituito con qualcos'altro.

167.7.9 SELECT

L'elemento SELECT delimita un ambiente attraverso cui si definiscono una serie di scelte possibili, che normalmente appaiono in forma di menu a scomparsa. Per questo, oltre a SELECT si devono utilizzare una serie di elementi OPTION con cui si indicano tali scelte possibili. Va tenuto in considerazione che l'attributo NAME viene indicato nel marcatore di apertura dell'ambiente SELECT.

Attributi specifici di SELECT

MULTIPLE

Questo attributo vale solo in quanto esistente o meno. Se presente, indica che sono ammissibili selezioni multiple, altrimenti è consentita la scelta di una sola voce.

Attributi specifici di OPTION

VALUE=x

Definisce il valore (numero o stringa) da abbinare alla scelta eventuale. La stringa che appare all'utente è quella che segue il marcatore OPTION di apertura, e se mancasse l'attributo VALUE, sarebbe quella stessa stringa a essere restituita in abbinamento al nome definito nel marcatore SELECT.

SELECTED

La presenza di questo attributo definisce una selezione predefinita.

Esempi

<SELECT NAME="codice-colori">
    <OPTION VALUE=0 SELECTED>Nero
    <OPTION VALUE=1 >Marrone
    <OPTION VALUE=2 >Rosso
    <OPTION VALUE=3 >Arancio
    <OPTION VALUE=4 >Giallo
    <OPTION VALUE=5 >Verde
    <OPTION VALUE=6 >Blu
    <OPTION VALUE=7 >Viola
    <OPTION VALUE=8 >Grigio
    <OPTION VALUE=9 >Bianco
</SELECT>

Presenta un menu di scelta a scomparsa per la selezione di un colore che poi viene convertito in un codice numerico corrispondente. Il nero, corrispondente allo zero, risulta predefinito.

167.8 Metodi e variabili

Si è ripetuto più volte che esistono differenze nel modo con cui i programmi gateway ricevono le informazioni dal server. Il modo fondamentale attraverso cui ciò viene controllato dal client, è la scelta del metodo della richiesta: GET o POST. Finora sono stati visti esempi che utilizzavano il metodo GET.

167.8.1 Metodo GET

Quando un client invia una richiesta utilizzando il metodo GET appende all'URI tutte le informazioni aggiuntive necessarie. In pratica, l'URI stesso comprende l'informazione. Per convenzione, la richiesta è distinta dalla parte dell'URI che identifica la risorsa attraverso un punto interrogativo, come nell'esempio seguente, dove la parola ciao è l'informazione aggiuntiva che rappresenta l'input per il programma cgi-test.sh.

http://www.brot.dg/cgi-bin/cgi-test.sh?ciao

È già stato descritto in che modo debbano essere codificati i caratteri riservati, per fare sì che quanto ottenuto sia sempre un URI valido.

Per convenzione, se il testo della richiesta che segue il punto interrogativo contiene il simbolo = (senza alcuna trasformazione), si intende che si tratti di una richiesta proveniente da un modulo FORM, altrimenti da un semplice elemento ISINDEX oppure da un'immagine con l'attributo ISMAP.

In pratica, se sembra una richiesta ISINDEX perché non appare il segno di assegnamento (=) non protetto in alcun modo, il programma gateway riceverà la stringa di richiesta attraverso gli argomenti della riga di comando e anche la variabile di ambiente QUERY_STRING, altrimenti li riceverà solo attraverso la variabile QUERY_STRING.

In questa situazione, in presenza di una richiesta GET, il programma gateway può concentrarsi nell'analisi della sola variabile QUERY_STRING.

http://www.brot.dg/cgi-bin/cgi-test.sh?nome=Pinco&cognome=Pallino&sesso=M

L'URI mostrato sopra rappresenta una richiesta proveniente (presumibilmente) da un modulo FORM, per la presenza dei simboli di assegnamento. Come si può osservare, ogni coppia <nome>=<valore> è collegata alla successiva attraverso il simbolo e-commerciale (&).

Il metodo GET, in quanto aggiunge all'URI la stringa di richiesta, permette all'utente di controllare e di memorizzare il flusso di dati, per esempio attraverso un segnalibro (bookmark). In pratica, con la semplice memorizzazione dell'URI, l'utente può riprendere un'operazione di inserimento di dati, senza dover ricominciare tutto dall'inizio.

Lo svantaggio nell'utilizzo di tale metodo sta nel fatto che esiste un limite alla dimensione degli URI, e di conseguenza anche alla quantità di dati che gli si possono accodare.

167.8.2 Metodo POST

Il metodo POST è stato progettato per porre rimedio ai limiti dell'altro metodo. Con questo, i dati dei FORM vengono inviati in modo separato dall'URI, e il gateway li riceve dal server attraverso lo standard input. Il metodo POST è generalmente preferibile.

167.8.3 Variabili di ambiente

Si è fatto riferimento più volte alle variabili di ambiente e al loro ruolo nel sistema di comunicazione tra il server e il programma gateway. Segue l'elenco di quelle più importanti.

Informazioni sul server

SERVER_SOFTWARE

Il nome e la versione del software utilizzato come server.

SERVER_NAME

Il nome del server.

SERVER_PROTOCOL

Il nome e la versione del protocollo utilizzato dal server.

SERVER_PORT

Il numero della porta di comunicazione utilizzata dal server.

GATEWAY_INTERFACE

Letteralmente, è l'interfaccia gateway, ovvero la versione del protocollo CGI utilizzato dal server.

PATH_INFO

Quando l'URI contiene l'indicazione di un percorso aggiuntivo, questa variabile riceve quel percorso.

PATH_TRANSLATED

Questa variabile viene utilizzata assieme a PATH_INFO, per indicare il percorso reale nel filesystem che ospita il server.

SCRIPT_NAME

La parte dell'URI che identifica il percorso del programma utilizzato come gateway.

Informazioni sulla connessione client/server

REQUEST_METHOD

Il metodo della richiesta (GET, POST).

REMOTE_HOST

Il nome del client. Se il nome non è disponibile, si deve fare uso della variabile REMOTE_ADDR che contiene l'indirizzo IP.

REMOTE_ADDR

Indirizzo IP del client.

AUTH_TYPE

Contiene l'eventuale metodo di autenticazione.

REMOTE_USER

Il nome dell'utente se si utilizza l'autenticazione.

Informazioni passate dal client al server

QUERY_STRING

Contiene la stringa di richiesta se si utilizza il metodo GET.

CONTENT_LENGTH

Contiene la dimensione in byte dei dati ricevuti dal client. Questa informazione è disponibile solo se si utilizza il metodo POST.

CONTENT_TYPE

Contiene la definizione del tipo di codifica dei dati ricevuti dal client e riguarda solo il metodo POST. La codifica più comune è application/x-www-form-urlencoded e significa che i dati sono stati codificati secondo lo standard utilizzato per il metodo GET: gli spazi sono convertiti in + e tutti i simboli speciali secondo la forma %hh, dove hh sono due cifre esadecimali.

Informazioni addizionali dal client

Quando il client invia una richiesta al server, prepara un'intestazione all'interno della quale possono essere inseriti diversi campi. Il contenuto di questi campi viene tradotto in altrettante variabili di ambiente il cui nome inizia per HTTP_ seguito dal nome del campo stesso. In particolare, i caratteri minuscoli sono convertiti in maiuscoli e i trattini sono sostituiti dal simbolo di sottolineatura. Seguono alcuni esempi.

HTTP_ACCEPT

Equivale al campo Accept.

HTTP_USER_AGENT

Equivale al campo User-Agent.

167.8.4 Un po' di pratica

Prima di iniziare a pensare a dei programmi gateway concludenti, conviene verificare quando scritto attraverso i programmi di analisi mostrati in precedenza: cgi-test.sh oppure cgi-test.pl. Negli esempi verrà mostrato sempre il primo di questi due, anche se il migliore per queste cose sarebbe il secondo.

Si può realizzare una pagina HTML contenente dei FORM, come nell'esempio seguente, che si rifà a esempi visti in precedenza.

<!-- form-test.html -->
<HTML>
<HEAD>
	<TITLE>Verifica del funzionamento dei FORM</TITLE>
</HEAD>
<BODY>

    <FORM ACTION="/cgi-bin/cgi-test.sh" METHOD="GET">

	<H2>Test di vari tipi di elementi di un FORM - metodo GET</H2>

	<INPUT TYPE=hidden NAME="nominativo" VALUE="Tizio" >

	<P>Inserisci il colore:
	    <INPUT NAME="colore" SIZE=20 VALUE="giallo">
	Inserisci la password:
	    <INPUT TYPE=password NAME="password-utente"
		TYPE=password SIZE=20></P>

	<P>Barrare la casella se si desidera ricevere propaganda:
	    <INPUT TYPE=checkbox NAME="propaganda" VALUE="SI" CHECKED >

	<P>Selezionare il contenitore dell'elaboratore:
	    orizzontale <INPUT TYPE=radio NAME="case"
		VALUE="desktop" CHECKED>
	    verticale <INPUT TYPE=radio NAME="case"
		VALUE="tower">
	    verticale ridotto<INPUT TYPE=radio NAME="case"
		VALUE="minitower"></P>

	<P>Scrivi qui due righe.
	    <TEXTAREA NAME="messaggio" ROWS=3 COLS=40 ></TEXTAREA></P>

	<P>Selezionare il codice attraverso il colore:
	    <SELECT NAME="codice-colori">
		<OPTION VALUE=0 SELECTED>Nero
		<OPTION VALUE=1 >Marrone
		<OPTION VALUE=2 >Rosso
		<OPTION VALUE=3 >Arancio
		<OPTION VALUE=4 >Giallo
		<OPTION VALUE=5 >Verde
		<OPTION VALUE=6 >Blu
		<OPTION VALUE=7 >Viola
		<OPTION VALUE=8 >Grigio
		<OPTION VALUE=9 >Bianco
	    </SELECT></P>

	<P><INPUT TYPE=image NAME="immagine" SRC="/test.jpg">

	<INPUT TYPE=submit VALUE="Invia la richiesta con il metodo GET"></P>

    </FORM>

	<HR>

    <FORM ACTION="/cgi-bin/cgi-test.sh" METHOD="POST">

	<H2>Test di vari tipi di elementi di un FORM - metodo POST</H2>

	<INPUT TYPE=hidden NAME="nominativo" VALUE="Tizio" >

	<P>Inserisci il colore:
	    <INPUT NAME="colore" SIZE=20 VALUE="giallo">
	Inserisci la password:
	    <INPUT TYPE=password NAME="password-utente"
		TYPE=password SIZE=20></P>

	<P>Barrare la casella se si desidera ricevere propaganda:
	    <INPUT TYPE=checkbox NAME="propaganda" VALUE="SI" CHECKED >

	<P>Selezionare il contenitore dell'elaboratore:
	    orizzontale <INPUT TYPE=radio NAME="case"
		VALUE="desktop" CHECKED>
	    verticale <INPUT TYPE=radio NAME="case"
		VALUE="tower">
	    verticale ridotto<INPUT TYPE=radio NAME="case"
		VALUE="minitower"></P>

	<P>Scrivi qui due righe.
	    <TEXTAREA NAME="messaggio" ROWS=3 COLS=40 ></TEXTAREA></P>

	<P>Selezionare il codice attraverso il colore:
	    <SELECT NAME="codice-colori">
		<OPTION VALUE=0 SELECTED>Nero
		<OPTION VALUE=1 >Marrone
		<OPTION VALUE=2 >Rosso
		<OPTION VALUE=3 >Arancio
		<OPTION VALUE=4 >Giallo
		<OPTION VALUE=5 >Verde
		<OPTION VALUE=6 >Blu
		<OPTION VALUE=7 >Viola
		<OPTION VALUE=8 >Grigio
		<OPTION VALUE=9 >Bianco
	    </SELECT></P>

	<P><INPUT TYPE=image NAME="immagine" SRC="/test.jpg">

	<INPUT TYPE=submit VALUE="Invia la richiesta con il metodo POST"></P>

    </FORM>

</BODY>
</HTML>

Come si può vedere sono presenti due FORM indipendenti: il primo utilizza il metodo GET, il secondo il metodo POST. Entrambi i FORM richiamano il programma gateway /cgi-bin/cgi-test.sh.


Figura 167.5: Richiamando il file HTML dell'esempio, form-test.html, con un programma client, si ottiene un modello simile a quello di questa figura. Qui viene mostrata solo la prima parte, perché ciò che resta è solo la ripetizione dello stesso modello utilizzando il metodo POST.

Si può già provare così, anche senza modificare alcunché. Se si invia la richiesta attraverso il modulo che utilizza il metodo GET, si osserverà che la richiesta va a fare parte dell'URI del programma gateway, e di conseguenza viene inserita nella variabile QUERY_STRING. Altrimenti, con il metodo POST la richiesta apparirà solo dallo standard input. In entrambi i casi, dovrebbe risultare codificata nello stesso modo (codifica URI).

nominativo=Tizio&colore=giallo&password-utente=&propaganda=SI&
case=desktop&messaggio=&codice-colori=0

Si può osservare in particolare la presenza della coppia nominativo=Tizio, inserita a titolo di esempio come campo nascosto, e costante. Se invece di inviare il modulo attraverso la selezione del tasto (submit) si utilizza l'immagine, si ottiene una stringa simile a quella seguente:

nominativo=Tizio&colore=giallo&password-utente=&propaganda=SI&
case=desktop&messaggio=&codice-colori=0&immagine.x=60&immagine.y=28

A questo punto, il lettore dovrebbe provare per conto proprio a compilare i campi, a modificare le selezioni, in modo da prendere dimestichezza con l'effetto generato dai moduli FORM.

167.9 Riferimenti

---------------------------

Appunti Linux 1999.09.21 --- Copyright © 1997-1999 Daniele Giacomini --  daniele @ pluto.linux.it


1.) L'uso del punto interrogativo rende la cosa intuitiva: la richiesta viene fatta attraverso un'interrogazione.


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]