Hello World! Introducere în CGIFlorin SabăuAcest articol își propune să fie o inițiere în tainele CGI, o interfață cu ajutorul căreia poate fi realizată interactivitatea între un server și calculatorul pe care sunt vizualizate paginile Web de pe serverul respectiv. Mulțumită World Wide Web-ului (WWW), aproape oricine poate pune la dispoziția celorlalți informații într-o formă vizuală plăcută. Probabil că ați navigat de multe ori pe Web și v-ați dat seama că acronimele teribile ca HTTP sau HTML nu sunt altceva decât un mod complicat de a spune Web și modalitatea prin care se prezintă informația pe Web. Web-ul s-a dovedit a fi un mediu propice pentru distribuirea informației așa cum se poate observa din imensa popularitate de care se bucură, ca și de creșterea sa exponențială din ultimii ani. Deși unii nu au fost convinși de utilitatea Web-ului și au pus creșterea sa pe seama publicității care i se face, acesta este, fără îndoială, o unealtă importantă în accesarea unei palete variate de informații. Deși pune la dispoziția utilizatorului o interfață foarte prietenoasă (bazată pe conceptul de hypermedia), există și alte forme de a distribui eficient date și informații. De exemplu, servicii ca FTP (File Transfer Protocol) și Gopher existau cu mult înaintea apariției World Wide Web-ului. De asemenea, e-mail-ul a reprezentat principala modalitate de comunicare pe Internet încă de la începuturile acestei rețele. Atunci, cărui fapt se datorează popularitatea Web-ului? Nu poate fi ignorat faptul că aspectul multimedia a contribuit mult, dar factorul determinant a fost interactivitatea sa. Pe lângă oferta de informații, fără capabilitatea de a primi informații de la utilizatori, Web-ul ar fi un mediu complet static, informația ar fi disponibilă doar în formatul definit de autor. Astfel în loc ca utilizatorul să fie nevoit să răsfoiască mai multe documente pentru a găsi informația dorită (ca și când ar avea în față o carte sau un dicționar), ar fi de preferat ca utilizatorul să testeze câteva cuvinte cheie care să specifice subiectul de interes, iar serverul Web să se ocupe de căutarea informațiilor utile. Deși serverul Web poate transmite și primi date, el are o funcționalitate limitată. În mod normal, el nu știe ce să facă cu informațiile pe care utilizatorul le introduce și de cele mai multe ori le ignoră. Pentru a spori capabilitățile serverului Web, acesta trebuie "învățat" și aici intră în scenă CGI.
Ce este CGI? Common Gateway Interface (CGI) este o interfață între serverul Web și utilizator. La un nivel teoretic, CGI sporește funcționalitatea serverului, prin posibilitatea sa de a interpreta datele introduse de utilizatorul care accesează serverul și de a returna informații în funcție de aceste date. Practic, CGI este o interfață care-l ajută pe programator să scrie programe care să comunice foarte ușor cu serverul. CGI pune la dispoziția programatorului o soluție simplă și portabilă pentru a îndeplini aceste deziderate. Există un protocol care definește un mod standard în care programele pot să comunice cu serverul Web. Astfel, fără prea multe cunoștințe din domeniul rețelelor sau al arhitecturii serverelor, se pot scrie programe în orice limbaj de programare dacă se generează un cod executabil care să ruleze pe respectivul server. Comunicarea între program și server se realizează prin intermediul intrării și ieșirii standard (standard input/output). Aceasta înseamnă că tot ceea ce trebuie să știm pentru a scrie un program CGI este să citim date de la intrarea standard și să tipărim date la ieșirea standard în limbajul de programare favorit. Cu excepția interpretării intrării și ieșirii standard, proiectarea și implementarea unei aplicații CGI sunt aproape echivalente cu proiectarea și implementarea oricărei alte aplicații. De exemplu, dacă vrem să scriem un program de tip "Hello World!", nu trebuie decât să folosim o funcție de tipul printf(), respectând formatul standard definit pentru programele CGI.
Ce limbaj să folosesc? Datorită faptului că CGI este o interfață comună (common interface), nu există limitări asupra limbajului de programare care poate fi folosit. De fapt, poate fi folosit orice limbaj care oferă suport pentru:
Limbajele se pot împărți în două mari categorii:
Care dintre cele două limbaje este mai bun? C sau Perl? Dacă doriți viteză la rulare probabil că veți alege C; în schimb, dacă doriți o paletă largă de funcții de procesare a textului sau doriți să scrieți repede un program CGI, probabil că Perl se va descurca mai bine. De asemenea, un factor important este și experiența anterioară dobândită cu unul dintre ele. Pentru început vom folosi C datorită faptului că este foarte răspândit, existând versiuni pentru majoritatea platformelor și sistemelor de operare. Având în vedere că nu toți cititorii au acces la un server Web și cum cele mai răspândite sisteme sunt cele pe care rulează Windows, pentru a încerca exemplele din acest articol recomandăm folosirea aplicației OmniHTTPd produsă de firma Omnicron. Această aplicație permite simularea comportamentului unui server, folosind un calculator obișnuit.
Primul program CGI Programarea CGI se poate reduce la două sarcini: citirea informațiilor din programul de navigare și tipărirea informațiilor înapoi în programul de navigare. Probabil că de multe ori, la accesarea unui site Web, ați fost nevoit să completați un formular cu datele dumneavoastră personale. În multe cazuri, toate aceste date, după ce se apasă butonul Submit (sau un alt buton care are același rol), sunt trimise de programul de navigare către un program CGI care rulează pe serverul Web. Acesta convertește informațiile într-un format cunoscut de el, le procesează și apoi trimite înapoi programului de navigare (și implicit utilizatorului) rezultatele; acestea pot fi, de exemplu, răspunsurile la o căutare complexă într-o bază de date stocată pe server. Cu alte cuvinte, programarea CGI constă în înțelegerea modului în care programul de navigare transmite datele furnizate de utilizator către server și a modului în care programul de navigare se așteaptă să primească rezultatele de la server. Pentru început vom vedea cum se poate scrie în C un program CGI foarte simplu (de tip "Hello World!"), urmând ca apoi să explicăm fiecare linie în detaliu. Va trebuie să introduceți codul sursă și să-l salvați sub numele HELLO.C. Acest fișier trebuie compilat, iar fișierul executabil trebuie mutat în directorul cu programe CGI de pe server (de obicei /cgi-bin pe sistemele UNIX). Dacă nu aveți acces la un server Web dar ați instalat aplicația OmniHTTPd, veți muta executabilul în directorul c:\httpd\cgi-bin\. Pentru a vizualiza rezultatul deschideți programul de navigare preferat și introduceți URL-ul http://adresa_server_web/cgi-bin/hello.exe. Dacă folosiți aplicația OmniHTTPd sau orice altă aplicație care permite simularea comportamentului unui server Web veți introduce URL-ul http://localhost/cgi-bin/hello.exe.
Listing HELLO.C #include <stdio.h> void main(void) { printf("Content-Type: text/html\r\n\r\n"); printf("<HTML>\n") printf(" <HEAD>\n"); printf(" <TITLE>\n"); printf(" Hello, World!\n"); printf(" </TITLE>\n"); printf(" </HEAD>\n"); printf(" <BODY>\n"); printf(" <H1>"); printf(" Hello, World!"); printf(" </H1>\n"); printf(" </BODY>"); printf("</HTML>\n"); } Sunt câteva lucruri care trebuie menționate. În primul rând, am folosit funcții simple de tipărire către stdout (standard output - ieșirea standard). În al doilea rând, prima instrucțiune printf (cu parametrul "Content-Type: text/html") nu apare la ieșire în programul de navigare deoarece un program CGI poate returna orice fel de informație către programul de navigare care trebuie să cunoască tipul informației respective (o pagină HTML, o imagine grafică, o secvență audio etc.). Programul de navigare determină acest tip prin intermediul header-ului "Content Type:". În cazul nostru este vorba de o pagină HTML (text/html). Forma generală a acestui header este: Content-Type: subtype/type unde "subtype/type" este un tip MIME (Multipurpose Internet Mail Extensions) valid. Tabelul 1 prezintă câteva dintre aceste tipuri:
Tip MIME Descriere Tabelul 1 text/html HyperText Markup Language (HTML) text/plain fișier text simplu image/gif fișier grafic .GIF image/jpeg fișier grafic .JPG audio/basic fișier sunet .au audio/x-wav fișier sunet .wav
Urmează apoi sursa paginii HTML propriu-zise. Trebuie remarcat faptul că header-ul și sursa sunt despărțite de o linie liberă ("\r\n"). Pentru a realiza programe CGI care să interacționeze cu utilizatorul trebuie să înțelegem mecanismul prin care programul de navigare trimite către programul CGI datele introduse de utilizator în formularele HTML.
Formularele HTML Cele mai importante marcaje HTML din punctul de vedere al programatorului de CGI-uri sunt <FORM> și <INPUT>. Practic, folosind aceste două marcaje putem realiza orice tip de formular care să permită utilizatorului introducerea datelor în vederea prelucrării de către programul CGI. Nu vom realiza o prezentare exhaustivă a celor două marcaje, ci vom sublinia doar elementele mai importante. Marcajul <FORM> este utilizat pentru a delimita, în cadrul fișierului HTML, porțiunea care este folosită de utilizator pentru a introduce date. Atributele marcajului specifică numele programului care va prelucra datele și locația sa (sub forma unui URL), tipul de codificare folosit și metoda cu care se face transferul datelor de intrare către programul CGI. Sintaxa acestui marcaj este: <FORM action="url" method=[post|get] enctype="..."> Atributul enctype nu este foarte important și de aceea este rar folosit. Este utilizat doar atunci când dorim să trimitem (upload) un fișier către server. Atributul action conține calea și numele programului CGI. După ce utilizatorul apasă butonul Submit, toate informațiile din formular sunt codificate și transmise către programul CGI prin una din metodele Post sau Get, selectată prin intermediul atributului method. Marcajul <INPUT> este utilizat pentru a crea câmpuri de editare de text, butoane radio, butoane de selecție etc. Cea mai simplă formă a marcajului <INPUT> este: <input type="tip"> unde tip poate lua valori ca:
Metodele GET și POST În momentul în care utilizatorul a terminat de introdus datele în formular și a apăsat butonul Submit, două tipuri de date sunt trimise către programul CGI: datele din formular și informații despre programul de navigare și despre server. Cele din cea de-a doua categorie sunt puse la dispoziția programului CGI prin intermediul variabilelor de mediu, în timp ce primele sunt disponibile ori printr-o variabilă de mediu (în cazul metodei GET), ori prin intermediul intrării standard (metoda POST). Indiferent dacă un formular este transmis unui program CGI sau nu, orice astfel de aplicație primește informații privitoare la programul de navigare și la server prin intermediul variabilelor de mediu. Aceste informații includ:
În continuare vom da câteva exemple de astfel de variabile de mediu:
Pentru a pune în aplicare cele prezentate până acum vom folosi o pagină HTML care conține un formular și un program CGI care va returna valorile tuturor variabilelor de mediu. Documentul HTML care generează o astfel de pagină Web este următorul:
Listing FORMULAR.HTML <html> <head> <title> Un formular simplu </title> </head> <body> <form action='http://localhost/ cgi-bin/formular.exe' method=post> <input type=text name='camp' size=15 maxlength=5> <br> <input type=radio name=radio value="primul" checked> Primul buton <br> <input type=radio name=radio value="al_doilea"> Al doilea buton <BR> <input type=checkbox name=check value="unu" checked> Unu <br> <input type=checkbox name=check value="doi" checked> Doi <br> <input type=password name=parol> <br> <input type=submit name='buton'> <input type=reset name='reset'> </form> </body> </html> Fișierul sursă pentru script-ul CGI care afișează valorile variabilelor de mediu este următorul:
Listing FORMULAR.C
#include <stdio.h> #include <stdlib.h> #include <string.h>
void main(void){ int l; char *s; char **p=environ; printf("Content-Type: text/html\r\n\r\n"); while (*p) printf("%s <BR>",*p++); if (!strcmp(getenv("REQUEST_METHOD"), "GET")) printf("Ati introdus(GET): %s<BR>", getenv("QUERY_STRING")); else{ l=atoi(getenv("CONTENT_LENGTH")); s=(char*)malloc(l); scanf("%s",s); printf("Ati introdus(POST): %s<P>",s); printf("<CENTER><H3><A href='%s'> \ Inapoi </CENTER> <BR>", getenv("HTTP_REFERER")); } } Fișierul formular.html trebuie copiat în rădăcina site-ului Web (sau c:\httpd\htdocs dacă folosiți aplicația OmniHTTPd), iar fișierul FORMULAR.C trebuie compilat, apoi executabilul generat trebuie copiat în directorul cgi-bin (c:\httpd\cgi-bin pentru OmniHTTPd). Din programul de navigare trebuie apelat URL-ul: http://siteweb/formular.html sau http://localhost/formular.html (dacă folosiți un server Web local - OmniHTTPd).
Codificarea URL Probabil v-ați dat deja seama că, pentru a trimite date server-ului, programul de navigare le codifică după un anumit format. Acest format se numește codificare URL (URL encoding). Aceasta a apărut datorită necesității de a codifica într-un anume fel URL-urile transmise prin e-mail, deoarece prin e-mail pot fi transmise doar primele 128 caractere ale setului de caractere ASCII. O parte din această codificare se referă la caracterele speciale cum ar fi Tab, Space, ghilimelele și, în general, caracterele extinse ale setului ASCII (cu numărul de ordine mai mare decât 127). De ce ar trebui să ne intereseze această codificare? Exsită două motive principale:
Referitor la primul aspect, codificarea se face astfel: atunci când programul de navigare întâlnește un caracter special, el îl înlocuiește cu un caracter procent (%) urmat de codul ASCII al caracterului respectiv în hexazecimal (cu două cifre). În tabelul 2 sunt prezentate caracterele speciale care au nevoie de codificare, precum și echivalentul lor hexazecimal.
Caracter Cod ASCII Tabelul 2 Tab 09 Space 20 " 22 ( 28 ) 29 , 2C . 2E ; 3B : 3A < 3C > 3E @ 40 [ 5B \ 5C ] 5D ^ 5E ` 60 { 7B | 7C } 7D ~ 7E
Pe lângă aceste caractere speciale prezentate, alte câteva caractere trebuie codificate deoarece în mod normal au o semnificație specială pentru server:
Referitor la al doilea tip de codificare folosit pentru datele introduse de utilizator într-un formular spre a fi transmise script-ului CGI, iată câteva reguli care stau la baza acestei codificări:
Florin Sabău este elev în clasa a XII-a la Liceul "Traian Lalescu" din Reșița. Poate fi contactat prin e-mail la adresa fsabau@cs.ro. [cuprins] |