Programmazione CGI - DB group, Unimore

Transcript

Programmazione CGI - DB group, Unimore
Programmazione CGI - 1
HTTP
client
"!#!
Possibilità di avere
HTTP
server
con informazioni dinamiche
Che tipo di elaborazione delle informazioni e
viene eseguita
Documento
HTML
CGI
Statica (la pagina è un
file, non modificabile)
dinamica
Java applet
statica
Java
applicazione
dinamica
semplice trasferimento
file dal server
qualunque elaborazione
sul nodo server
codice dal server non
modificabile, esecuzione
sul client
server elabora
dinamicamente il codice
(in base alla richiesta),
esecuzione dinamica sul
client
Programmazione CGI - 2
Common Gateway Interface (CGI)
4657598;:=<>46?@:=A6B7:
M>NPOQM>RTS7M
HTTP
client
$%&'%()*,+
$%)-.)*,+
HTTP
server
/1032
CDCEFGH"KJLHKF
CDCEFGH"IFGJEJ
è uno
per interfacciare un server WWW con
applicazioni esterne (residenti sulla macchina server)
CGI fornisce all’utente la capacità di eseguire una applicazione
sulla macchina server remota
CGI
dinamic
a
Qualunque
elaborazione,
La risposta ottenuta dal server è "dinamica", in quanto
risultante dalla esecuzione di un programma sul server.
Programmazione CGI - 3
Programmazione CGI
Una applicazione CGI permette agli utenti di eseguire una
applicazione sul nodo dove risiede il server www.
Applicazioni CGI possono essere scritte in: C/C++, Fortran,
PERL, TCL, Any Unix shell, Visual Basic ….etc etc
Normale attivazione di una CGI:
• Si invia al server un messaggio (ciò avviene
tipicamente riempiendo moduli,
, i cui dati
serviranno come input al programma)
• Il messaggio scatena l'esecuzione del programma CGI
• Il programma CGI genera come output una pagina
HTML in cui inserisce i risultati della sua esecuzione
Interfaccia tra server WWW e applicazione CGI
•
•
•
: il server manda come standard input
alla applicazione CGI i dati ricevuti dal client (browser).
Il numero di byte totali è nella varabile di ambiente
CONTENT_LENGTH.
•
L’input della applicazione è
costituito da insiemi di stringhe nome=valore. In
pratica, l’input è formato da una serie di variabili con un
nome e un valore. Le differenti variabili sono separate
da
•
: l’applicazione CGI manda il risultato
dell-elaborazione sullo standard output (in formato
HTML), verso il server, il quale prende i dati e li manda
al client.
Programmazione CGI - 4
Client HTTP
server HTTP
CGI
Tipicamente, uso di
<TITLE>Esempio di Form </TITLE>
<H1>Esempio di Form </H1>
<FORM METHOD="POST" ACTION="http://wwwlia.deis.unibo.it/cgi-bin/post-query">
Inserisci del testo: <INPUT NAME="entry">
e premi per invio: <INPUT TYPE="submit"
VALUE="Invio">
</FORM>
Visualizzazione
Programmazione CGI - 5
Client HTTP
server HTTP
CGI
Attributi del
<TITLE>Esempio di Form </TITLE>
<H1>Esempio di Form </H1>
<FORM UWVWXZY\[\] =" ^Z_W`\a " bWcWd\eZf\g ="http://wwwlia.deis.unibo.it/cgi-bin/post-query">
Inserisci del testo: <INPUT NAME="entry">
e premi per invio: <INPUT TYPE="submit"
VALUE="Invio">
</FORM>
Dove:
hWiWj\kZl\m
nWoWpZq\r\s
URL di chi processa la query
metodo usato per sottomettere il form:
tZuWv\w
il form con i dati è spedito come data body
(metodo consigliato), cioè come dati che
fanno parte del testo del messaggio HTTP
x\yWz
il form con i dati è spedito attaccato
all’URL, cioè come parte integrante
dell’URL del messaggio
(action?name=value&name=value)
caso GET
http://www-lia.deis.unibo.it
/cgi-bin/get-query?entry=testo
caso POST
http://www-lia.deis.unibo.it
/cgi-bin/post-query
e come data body:
entry=testo
Programmazione CGI - 6
Applicazione CGI
server HTTP
Applicazione CGI usa
per mandare al server i
dati. I dati sono identificati da un header.
Tipi di dati forniti:
• full document con il corrispondente MIME type (text/html,
text/plain per testo ASCII, etc.)
Esempio: per spedire una pagina HTML
Content-type: text/html
<HTML><HEAD>
<TITLE>output di HTML da script CGI</TITLE>
</HEAD><BODY>
<H1>titolo</H1>
semplice <STRONG>prova</STRONG>
</BODY></HTML>
• reference a un altro documento
Esempio: riferisco un documento gopher
Content-type: text/html
Location: gopher://httprules.foobar.org/0
<HTML><HEAD>
<TITLE > Sorry ... it moved </TITLE>
</HEAD><BODY>
<H1>go to gopher </H1>
Now available at
<A HREF="gopher://httprules.foobar.org/0">
new location</A> of gopher server.
</BODY></HTML>
Programmazione CGI - 7
Applicazione CGI
Esempio:
generazione della pagina di risposta
(caso full document)
#include <stdio.h>
...............
main(int argc, char *argv[]) {
int cl;
generazione di un full document in risposta
{}|\~ZW€\ƒ‚„…W†ZW€Z‡\W€\ˆ\€Z‰Z{W‡ƒŠ
€Z‡\‹W€\ŒZW€Ž}\ZWZ}„\‘}’
cl = atoi(getenv("“\”\•W–Z—\•W–˜W™\—\•\šW–Z› "));
for(x=0;cl && (!feof( œ\ZžWŸZ ));x++) {
...
elaborazione dell’input (stdin)
...
/* L’input ad esempio sara’:
“entry=ciao&Submit=Invio”
}
¡}¢\£Z¤W¥\¦ƒ§¨©WªW«Z¬\­\®\¯W¢Z°
¡}¢\£Z¤W¥\¦ƒ§¨·W¸Z®
±\¯W²Z®W³\¥\²©}´ZªW«Z¬}¨\µ}¶
²Z®Z¹\º}£\¥\¥Z¯\»
for(x=0; x <= m; x++)
¼\¼\¼¨\µ}¶
½}¾\¿ZÀWÁ\ƒÃÄ}Å\Å\Å\Å\Å\Å\Å\Å\Å\Å\ÅÄ}Æ
Å\Å\Å
Æ
Å\Å\Å\ÅÇ}È
}
Programmazione CGI - 8
ESEMPIO CON METODI POST E GET
Programmazione CGI - 9
SORGENTE HTML
<H1>Fondamenti di Informatica D</H1>
<I><P>Prof. <A
HREF="http://www.dbgroup.unimo.it/Vincini.html"
>Maurizio Vincini</I></A> </P>
<HR>
<br>
<FONT SIZE="5"><B>Esempio di Inserimento dati Lettura variabili d’ambiente</B></FONT>
<br>
<H1>Metodo POST</H1>
<FORM ACTION="LeggiVariabili.exe" METHOD=post>
<TABLE border="0" cellpadding="3"
cellspacing="3" WIDTH="100%">
<tr><td colspan="5" align="right">
</td></tr>
<tr>
<P><td BGCOLOR="#76b6f2" width="200"><b>Stringa
inserita</b></td>
<td><INPUT NAME="var1"></td></P>
</tr>
</TABLE>
<BR>
<INPUT TYPE="submit" VALUE="Inserisci"
id=submit name=submit>
<INPUT TYPE="reset" VALUE="Reset"></P>
</FORM>
<br>
Programmazione CGI - 10
<H1>Metodo GET</H1>
<FORM ACTION="LeggiVariabili.exe" METHOD=get>
<TABLE border="0" cellpadding="3"
cellspacing="3" WIDTH="100%">
<tr><td colspan="5" align="right">
</td></tr>
<tr>
<P><td BGCOLOR="#76b6f2" width="200"><b>Stringa
inserita</b></td>
<td><INPUT NAME="var1"></td></P>
</tr>
</TABLE>
<BR>
<INPUT TYPE="submit" VALUE="Inserisci"
id=submit name=submit>
<INPUT TYPE="reset" VALUE="Reset"></P>
</FORM>
Supponiamo di inserire “pippo” e
sottomettere
Programmazione CGI - 11
CON POST
Programmazione CGI - 12
CON GET
Programmazione CGI - 13
Variabili d’AMBIENTE di MS IIS 4.0m
CLASSPATH=d:\progra~1\interb~1\interclient\interclient.jar
COMPUTERNAME=ZEUS
ComSpec=C:\WINNT\system32\cmd.exe
CONTENT_LENGTH=10
CONTENT_TYPE=application/x-www-form-urlencoded
GATEWAY_INTERFACE=CGI/1.1
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg, application/vnd.ms-powerpoint,
application/vnd.ms-excel, application/msword, */*
HTTP_ACCEPT_LANGUAGE=it
HTTP_CONNECTION=Keep-Alive
HTTP_HOST=zeus.ing.unimo.it
HTTP_REFERER=http://zeus.ing.unimo.it/FondD/esempio1.html
HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 5.5;
Windows NT 5.0)
HTTP_COOKIE=ASPSESSIONIDGQGGGQBR=GPOBELMCB
OJALNDAIDOKDGBO
HTTP_CONTENT_LENGTH=10
HTTP_CONTENT_TYPE=application/x-www-form-urlencoded
HTTP_ACCEPT_ENCODING=gzip, deflate
HTTPS=off
INCLUDE=C:\Program Files\Mts\Include
INSTANCE_ID=1
LIB=C:\Program Files\Mts\Lib
LOCAL_ADDR=155.185.48.170
NUMBER_OF_PROCESSORS=1
Os2LibPath=C:\WINNT\system32\os2\dll;
OS=Windows_NT
Path=C:\usr\xduninst;C:\usr\X11R6\bin;D:\orant\bin;C:\WINN
T\system32;C:\WINNT;C:\Program
Files\Mts;C:\PROGRA~1\ULTRAEDT
PATH_TRANSLATED=C:\Inetpub\wwwroot
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.VBE;.JSE;.WSF
Programmazione CGI - 14
;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 5 Model 2 Stepping
12, GenuineIntel
PROCESSOR_LEVEL=5
PROCESSOR_REVISION=020c
REMOTE_ADDR=155.185.48.13
REMOTE_HOST=155.185.48.13
REQUEST_METHOD=POST
SCRIPT_NAME=/Fond-D/LeggiVariabili.exe
SERVER_NAME=zeus.ing.unimo.it
SERVER_PORT=80
SERVER_PORT_SECURE=0
SERVER_PROTOCOL=HTTP/1.1
SERVER_SOFTWARE=Microsoft-IIS/4.0
SystemDrive=C:
SystemRoot=C:\WINNT
USERPROFILE=C:\WINNT\Profiles\Default User
windir=C:\WINNT
Programmazione CGI - 15
CODICE C DELL’ESEMPIO
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<string.h>
<ctype.h>
char InputBuffer[4096];
/* Programma Principale */
int main(int argc, char *argv[]) {
int ContentLength;
int i;
char *p;
char *pRequestMethod;
char *c;
/* Intestazione della pagina creata */
//printf("Content-type: text/plain\n");
printf("Content-type: text/html\n");
/* Fine dell’header */
printf("\n");
/* Scrive le variabili di input */
printf("argc = %d\n<BR>\n",argc);
for (i=0;i<argc;i++) {
printf("argv[%d]%s\n<BR>\n",i,argv[i]);
}
printf("\n<BR>\n");
/* Visualizza le variabili d’ambiente */
DisplayEnvVars();
printf("\n");
/* Acquisizione metodo di richiesta (POST o
GET) */
pRequestMethod = getenv("REQUEST_METHOD");
Programmazione CGI - 16
if (pRequestMethod==NULL) {
return 0;
}
if (_stricmp(pRequestMethod,"POST")==0) {
/* Read in the data from the client */
p = getenv("CONTENT_LENGTH");
if (p!=NULL) {
ContentLength = atoi(p);
} else {
ContentLength = 0;
}
if(ContentLength>sizeof(InputBuffer)-1)
{
ContentLength =
sizeof(InputBuffer)-1;
}
// legge da stdin la stringa inviata
// tramite POST
fgets(InputBuffer,ContentLength+1,stdin);
i = strlen(InputBuffer);
printf("Stringa inviata dal Form: <FONT
COLOR=""blue"">%s</FONT>\n<BR>\n",InputBuffer);
// legge il valore della variabile
// d’ambiente CONTENT_TYPE
p = getenv("CONTENT_TYPE");
if (p==NULL) {
return 0;
}
if (_stricmp(p,"application/x-www-formurlencoded")==0) {
strcpy(p, InputBuffer);
// Trova il valore della variabile var1
c = GetField("var1", p);
if (c != NULL) {
printf("La
variabile
var1
vale:
<FONT COLOR=""red""> %s </FONT>", c);
} else {
printf("La
variabile
var1
&egrave; NULL");
}
} else {
Programmazione CGI - 17
/* Visualizza i dati */
printf("Input = %s\n",InputBuffer);
}
} else
if (_stricmp(pRequestMethod,"GET")==0) {
/* Acquisizione della stringa inviata
tramite FORM/GET */
p = getenv("QUERY_STRING");
if (p!=NULL) {
strncpy(InputBuffer,p,sizeof(InputBuffer));
printf("Stringa inviata dal Form: <FONT
COLOR=""blue"">%s</FONT>\n<BR>\n",InputBuffer);
strcpy(p, InputBuffer);
c = GetField("var1", p);
if (c != NULL) {
printf("La
variabile
var1
vale:
<FONT COLOR=""red""> %s </FONT>", c);
} else {
printf("La
variabile
var1
&egrave; NULL");
}
}
}
return 0;
}
Programmazione CGI - 18
/*
* Visualizza tutte le variabili d’ambiente
*/
void DisplayEnvVars(void) {
int i;
i = 0;
while (_environ[i]) {
printf("%s\n<BR>\n",_environ[i]);
i++;
}
printf("\n<BR>\n");
}
The _environ variable is a pointer to an array of pointers
to the multibyte-character strings that constitute the
process environment. _environ is declared in STDLIB.H.
/* Ritorna il valore della variabile Item
contenuta nella stringa Field */
char *GetField(char *Item, char *Field) {
char *p;
char *s;
p = strtok(Field,"&");
while (p!=NULL) {
s = ValueField(p);
//printf("Valore di variabile(%s)
<BR>\n",p, s);
if (strcmp(p, Item) == 0) return s;
// strtok: cerca il NULL fino al
// prossimo carattere &
p = strtok(NULL,"&");
}
=
%s
return NULL;
}
/* Ritorna il valore della variabile */
char *ValueField(char *Item) {
Programmazione CGI - 19
char *p;
p = strchr(Item,’=’);
if (p==NULL) return NULL;
*p++=’\0’;
urlDecode(Item);
urlDecode(p);
return p;
}
/* Decodifica la stringa in input che utilizza
il % e lo space */
void urlDecode(char *p) {
char *pD;
pD = p;
while (*p) {
if (*p==’%’) {
/* i 2 char successivi sono la rappresentazione hex del carattere in esame */
p++;
// isxdigit ritorna un valore != 0 nel
//caso in cui il char sia di tipo esadecimale
if (isxdigit(p[0]) &&
isxdigit(p[1])) {
*pD++ = (char) TwoHex2Int(p);
p += 2;
}
} else {
if (*p==’+’) {
*pD++ = ’ ’;
p++;
} else
*pD++ = *p++;
}
}
*pD = ’\0’;
}
/* The string starts with two hex characters.
Return an integer formed from them. */
static int TwoHex2Int(char *pC) {
Programmazione CGI - 20
int Hi;
int Lo;
int Result;
Hi = pC[0];
if (’0’<=Hi && Hi<=’9’)
Hi -= ’0’;
} else
if (’a’<=Hi && Hi<=’f’)
Hi -= (’a’-10);
} else
if (’A’<=Hi && Hi<=’F’)
Hi -= (’A’-10);
}
Lo = pC[1];
if (’0’<=Lo && Lo<=’9’)
Lo -= ’0’;
} else
if (’a’<=Lo && Lo<=’f’)
Lo -= (’a’-10);
} else
if (’A’<=Lo && Lo<=’F’)
Lo -= (’A’-10);
}
Result = Lo + 16*Hi;
return Result;
{
{
{
{
{
{
}
Programmazione CGI - 21