UN SINGOLO COMPONENTE... ?
• Finora ci siamo concentrati su un singolo
programma = un singolo componente
– si leggono i dati di ingresso ...
– ... si elabora (computazione) ...
– ... si scrivono i risultati in uscita.
• Ma oggi quasi mai un’applicazione consiste in un singolo componente!
– un componente acquista molto più valore se
può cooperare a creare progetti più grandi
– elaborazione distribuita su rete
ARCHITETTURE MULTI-COMPONENTE
• componenti software e
hardware eterogenei
• ogni componente fornisce servizi agli altri componenti e usa i servizi da
essi forniti
• necessità di protocolli di
comunicazione
• esecuzione distribuita nel
tempo e nello spazio
ARCHITETTURA CLIENTE / SERVITORE
Servitore:
• un qualunque ente computazionale capace di
nascondere la propria organizzazione
interna
• presentando ai clienti una precisa
interfaccia per lo scambio di informazioni
Cliente:
• qualunque ente in grado di invocare uno o
più servitori per svolgere il proprio compito
IL MODELLO INTERNET
Cliente = browser Web
– Internet Explorer, Netscape Navigator, ...
Browser Web
(cliente)
Server Web
rete Internet
Servitore =
server Web
(sul sito)
IL PROTOCOLLO DI COMUNICAZIONE
HTTP: HyperText Transfer Protocol
1) il cliente invia al server l’identificatore della
pagina richiesta (URL)
http://www.unibo.it/studenti/stud.html
2) il server recupera il file corrispondente a
quella pagina...
..../studenti/stud.html
3) ... e lo invia al cliente (byte per byte)
IL PROTOCOLLO DI COMUNICAZIONE
Browser Web
(cliente)
http://..../studenti/stud.html
1
3
Server Web
2
IL PROTOCOLLO DI COMUNICAZIONE
HTTP: HyperText Transfer Protocol
Pregio:
• è un protocollo molto semplice da gestire e
da implementare
Difetto:
• nella versione base, è poco flessibile
– il contenuto delle pagine web è prefissato
– il server non fa alcuna elaborazione, si limita a
prendere un file e spedirlo
HTTP: ESTENSIONI
Obiettivo:
• dare al server la possibilità di rispondere a
una richiesta in modo “personalizzato” e
flessibile (non solo fisso a priori)
– esempio: fornire i risultati di una ricerca
Come?
• rendendo il server capace di eseguire un
programma per rispondere alla richiesta.
CGI: Common Gateway Interface
HTTP: ESTENSIONI
Risultato:
• qualunque programma può fornire i suoi
servizi sul web
– non più solo su un computer isolato!
• non importa il linguaggio in cui è scritto
• non importa come elabora (computazione)
• importa che gestisca input e output nei modi previsti dagli standard, ossia che segua il
MODELLO DI COORDINAZIONE previsto.
HTTP + CGI
Con CGI, HTTP diviene aperto e flessibile:
1) il cliente invia al server l’URL della pagina
richiesta, che però non è una vera pagina,
ma il nome di un programma (xxxx):
http://www.unibo.it/cgi-bin/xxxx
2) il server esegue il programma xxxx...
..../cgi-bin/xxxx
3) ... e invia il risultato al cliente.
HTTP + CGI
Browser Web
(cliente)
http://..../cgi-bin/xxxx
1
3
Server Web
2
Programma
xxxx
HTTP + CGI
Quindi:
• è il programma che risponde al cliente,
non più il server (fa solo da tramite)
• tutto quello che il programma scrive sullo
standard output viene trasferito “pari pari”
al cliente (il browser Web)
– semplice testo, testo HTML, immagini, altro...
• si può trasferire di tutto: basta che il cliente
sappia come trattare quello che gli arriva.
CGI: UN MINI-ESEMPIO
Un programma C che stampa “Hello World”...
main(){
printf(“Hello World!”);
}
...
CGI: UN MINI-ESEMPIO
... portato “sulla rete”:
Fondamentale il
“doppio a capo”
main(){
printf(“Content-type: text/plain\n\n”);
printf(“Hello World!”);
}
forma standard per avvertire il
browser di “cosa gli sta arrivando” (in
questo caso testo semplice, senza
formattazioni particolari)
MINI-ESEMPIO: VARIANTE
Un programma C che stampa “Hello World”
come pagina HTML
Questa volta stiamo
inviando testo HTML
main(){
printf(“Content-type: text/html\n\n”);
printf(“<H1>Here we are!</H1>”);
printf(“<P><H2>Hello World!</H2>”);
fflush(stdout);
“doppio a capo”
}
opportuno svuotare il buffer di output
per garantire che tutto il testo sia
effettivamente inviato
UNA PRECISAZIONE
• Questi programmi devono essere compilati
come normali programmi da console, non
come programmi (pseudo-) grafici!
– il server presuppone di poter parlare col
programma tramite i normali canali di I/O,
non tramite finestre di un qualche tipo!
• Quindi, non si può usare il Turbo C!
• Occorre DJgpp
– o un qualunque compilatore C che produca
eseguibili “da linea di comando” (DOS-like)
E PER FARE LE PROVE..?
• Non è necessario avere accesso a un server web situato chissà dove
• È possibile installarne uno localmente, sul
proprio computer
– ce ne sono a decine in rete, molti gratuiti...
– ...ma non tutti supportano bene le CGI!
• Sul sito del corso trovate Vq Server
– un web server scritto in Java (richiede Java per
funzionare), molto completo, e gratuito!
HTTP + CGI
• Al momento, però, il programma non riceve
dati di ingresso, quindi ha un output fisso!
• Invece, vogliamo che il cliente (browser)
possa inviare al programma opportuni dati
di ingresso per guidarne l’elaborazione.
Come fare?
Due possibili modi:
– con il sub-protocollo GET
– con il sub-protocollo POST
INVIO DI DATI con GET
• Il cliente invia i dati appendendoli all’URL
– un punto interrogativo come separatore iniziale
– seguito da qualunque cosa, ma senza spazi!
http://www.unibo.it/cgi-bin/xxxx?dati
• il server pone tutto ciò che segue il ? nella
variabile di ambiente QUERY_STRING
• il programma può recuperarla con la
funzione di libreria getenv() [in stdlib]:
char *s = getenv("QUERY_STRING")
ESEMPIO
Un programma C che ristampa quello che riceve (eco):
main(){
char *st = getenv("QUERY_STRING");
printf(“Content-type: text/plain\n\n”);
printf(“Buongiorno %s !”, st);
fflush(stdout);
Ricordare il
}
“doppio a capo”
ristampa la stringa
st che ha ricevuto
ESEMPIO
Il browser può invocarlo ad esempio così:
ristampa la stringa
che ha ricevuto
L’URL ha la forma:
.../cgi-bin/...
.../cgi/....
UNA RIFLESSIONE SULL’ESEMPIO
• Certo, questo esempio è estremamente
banale, perfino inutile...
• ..ma dimostra che “portare un programma
sul Web” è semplicissimo
basta rispettare il modello di coordinazione
previsto dallo standard (qui, CGI)
• Anche un programma che da solo sarebbe
stato di modesta utilità, portato sul Web può
essere utile ad altri
– diventa accessibile da tutto il mondo!
I MODULI (FORM)
• In pratica, nessuno si sogna di scrivere i
dati nell’URL “a mano”
• Tipicamente, l’utente compila un modulo
grafico e preme un bottone per inviare i dati
UN “FORM” scritto in HTML
• Il risultato è che il cliente (browser):
– prepara la stringa dati da inviare
– la appende al ? nel modo previsto
I MODULI (FORM)
Qui si scrive il testo da
inviare al programma
Quando si preme il
bottone, il testo viene
inviato
MODULI... E RISULTATI
La stringa inviata ha
una forma particolare:
Campo=Valore
Riscrive esattamente la
stringa ricevuta
RISULTATI... E MODULI
Questo campo di
testo si chiamava
testo
Il testo scritto era
PaolinoPaperino
Perciò, la stringa inviata è
stata
testo=PaolinoPaperino
IL MODULO (HTML)
<TITLE> Esempio di form </TITLE>
<H1> Esempio di form </H1>
Protocollo GET
<FORM METHOD="GET"
ACTION="http://localhost/cgi/enrico
/prova0.exe" >
Azione da compieInserisci il testo:
re quando si preme
<INPUT NAME="testo">
il pulsante invio
e poi premi invio:
<INPUT TYPE="submit" VALUE="invio">
</FORM>
IL MODULO (HTML)
<TITLE> Esempio di form </TITLE>
<H1> Esempio di form </H1>
<FORM METHOD="GET"
Il campo di testo
ACTION="http://localhost/cgi/enrico
Il pulsante che
(di nome testo)
/prova0.exe" >
attiva l’azione (tipo
submit), chiamato
Inserisci il testo:
<INPUT NAME="testo"> invio nel modulo
e poi premi invio:
<INPUT TYPE="submit" VALUE="invio">
</FORM>
INVIO DI DATI CON I MODULI
• Dunque, quando si compila un modulo, la
stringa inviata al programma (con GET) ha
sempre la forma standard seguente:
...?nome1=valore1&nome2=valore2&...
dove
– nome1, nome2, ... sono i nomi dei campi
(di testo, di selezione,...)
– valore1, valore2, ... sono i testi effettivamente scritti nei rispettivi campi
UN MODULO PIÙ COMPLESSO
Due campi di testo, denominati rispettivamente Nome
e Cognome
Due pulsanti, chiamati
conferma e annulla
(il primo invia, il secondo
cancella il modulo)
IL RISULTATO
La stringa inviata ha la forma standard
Nome=Paolino&Cognome=Paperino
IL MODULO PIÙ COMPLESSO (HTML)
<H1> Esempio di form </H1>
Un diverso programma
<FORM METHOD="GET"
ACTION="http://localhost/cgi/prova1.exe" >
Inserire i seguenti dati:<p>
Inserire il nome: <INPUT NAME="Nome"><br>
Inserire il cognome: <INPUT NAME="Cognome">
<p>
i due campi di testo
<INPUT TYPE="submit" VALUE="conferma">
<INPUT TYPE="reset" VALUE="annulla">
</FORM>
i due pulsanti (il tipo submit invia, il
tipo reset cancella il modulo)
IL PROGRAMMA
Il programma riceve una stringa in forma
standard e deve estrarre i vari pezzi
main(){
char cognome[80], nome[80], *st;
printf("Content-type: text/plain\n\n");
st = getenv("QUERY_STRING");
estrai(st, "Nome", nome);
estrai(st, "Cognome", cognome);
printf("Buongiorno %s %s!\n\n",
nome, cognome);
I nomi dei campi di testo del modulo
}
(attenzione: devono essere identici!)
IL PROGRAMMA
La funzione estrai(char*, char*, char*)
int estrai(char s[], char parametro[],
char valore[]) {
const char separatore = '&';
char *fine, *pos = strstr(s,parametro);
if (pos==NULL) return 1; /* non c’è */
pos += strlen(parametro)+1;
fine = strchr(pos,separatore);
if (fine==NULL) fine = pos + strlen(pos);
strncpy(valore,pos,fine-pos);
valore[fine-pos]='\0';
return 0;
}
IL PROGRAMMA
La funzione estrai(char*, char*, char*)
int estrai(char s[], char parametro[],
char valore[]) {
parametro=valore
const
char separatore = '&';
ci si *fine,
posiziona*pos
dopo =
l’= strstr(s,parametro);
parametro=valore&
char
if (pos==NULL) return 1;si cerca
/* non
c’è (se
*/ c’è)
l’& finale
pos += strlen(parametro)+1;
fine = strchr(pos,separatore);
if (fine==NULL) fine = pos + strlen(pos);
strncpy(valore,pos,fine-pos);
valore[fine-pos]='\0';
finalmente0;si ricopia in
se l’& finale non c’è, si
return
valore
il pezzo che serve
prende fino a fine stringa
}
Da GET a POST
• Finora, per inviare dati al programma CGI
abbiamo sfruttato il sub-protocollo GET
– Pro: è semplice, è facile da gestire
– Contro: è inadatto a inviare molti dati (la variabile QUERY_STRING ha limiti di lunghezza)
• Questi limiti si superano con il sub-protocollo POST
– i dati sono inviati sullo standard input del
programma
– richiede obbligatoriamente un modulo (form) per
inviare i dati (non si possono appendere all’URL)
INVIO DI DATI con POST
• È indispensabile usare un modulo (form)
• Quando si preme il pulsante di invio, il
browser invia i dati al server...
• .. che li ridirige sul canale d’input standard
del programma
– i dati si possono quindi recuperare con normali
letture da input
– non si passa più dalle variabili di ambiente del
sistema operativo, quindi non ci sono limiti di
dimensione
INVIO DI DATI con POST
Quale formato usa POST per inviare i dati?
• di norma, usa lo stesso formato di GET:
nome1=valore1&nome2=valore2&...
• Se però si specifica un particolare tipo di
codifica (enctype), il browser usa quello
• Ad esempio, con
enctype="multipart/form-data”
il browser invia i dati su righe separate, uno
per riga, separati da righe speciali e righe
vuote.
LO STESSO MODULO DI POCO FA
Due campi di testo, denominati rispettivamente Nome
e Cognome
Due pulsanti, chiamati
conferma e annulla
(il primo invia, il secondo
cancella il modulo)
...CHE USA POST (CASO BASE)
<H1> Esempio di form </H1>
Un terzo programma
<FORM METHOD="POST"
ACTION="http://localhost/cgi/prova2.exe" >
Inserire i seguenti dati:<p>
Inserire il nome: <INPUT NAME="Nome"><br>
Inserire il cognome: <INPUT NAME="Cognome">
<p>
<INPUT TYPE="submit" VALUE="conferma">
<INPUT TYPE="reset" VALUE="annulla">
</FORM>
IL PROGRAMMA
Il programma fa l’eco di tutto ciò che riceve:
main(){
char buf[1024];
printf("Content-type: text/plain\n\n");
printf("Risposta:\n\n");
while(gets(buf)) printf("%s\n", buf);
}
Ipotesi: righe non più lunghe di 1024 caratteri
IL RISULTATO (NEL CASO BASE)
Niente più dati
appesi all’URL
La stringa inviata ha la forma standard
Nome=Paolino&Cognome=Paperino
IL POST “multipart/form-data”
<H1> Esempio di form </H1>
Lo stesso programma
<FORM METHOD="POST"
ACTION="http://localhost/cgi/prova2.exe"
enctype="multipart/form-data" >
Inserire i seguenti dati:<p>
Una diversa codifica
Inserire il nome: <INPUT NAME="Nome"><br>
Inserire il cognome: <INPUT NAME="Cognome">
<p>
<INPUT TYPE="submit" VALUE="conferma">
<INPUT TYPE="reset" VALUE="annulla">
</FORM>
... E IL DIVERSO RISULTATO
I dati sono inviati uno per
riga, separati da righe
speciali e da una riga vuota
IL CODICE FISCALE.. SUL WEB!!
Ricordate l’esercizio sul codice fiscale?
• una delle varianti prevedeva proprio il
formato di dati tipico di GET e POST
(caso base)
• adottando tale formato di input, il programma può essere “portato sul Web” senza
sforzo...
• ...e immediatamente un servizio importante
risulta disponibile a tutti!
Scarica

24-CGI e HTML