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\ WZWZ\W\\ZZ{W Z\W\ZW}\ZWZ}\} cl = atoi(getenv("\\WZ\WW\\\WZ ")); for(x=0;cl && (!feof( \ZWZ ));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 è 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 è 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