Scripturi CGI
LOGO

Cum se poate incepe prima afacere pe Internet

Harta graficaHomeAfaceri onlineWebdesignCarti in format electronicArticoleHarta sitului

HOME
E-BUSINESS

WEBDESIGN

E-BOOKS
ARTICOLE
  Afaceri online
 < Webdesign >
  Comert electronic
  Programe afiliate

  E-book
 
Diverse
HARTA SIT


[ Sign my Guestbook] - [Read my Guestbook ]
[Guestbook by TheGuestBook.com]

Subscrieti la lista de discutii
Prima afacere pe Internet

Chat Chat

Trimite un email

Trafic counter

Site Meter


Scripturi CGI
Pagini Web generate dinamic

Autor :Péter Csaba

Calea cea mai directa catre programarea Web o reprezinta scripturile CGI. Însa pentru a putea scrie astfel de programe sunt necesare câteva cunostinte de baza privind protocolul HTTP si modul în care serverul Web ruleaza scripturi CGI.

Cu aproape trei ani în urma, am prezentat - ca programator Perl - ideile de baza privind modul în care se scriu în Perl scripturi CGI care sa fie sigure din punct de vedere al securitatii serverului pe care ruleaza (vezi "Byte România", Iulie 1997, http://www.byte.ro/ byte97-07/perl.htm). Mai târziu, am prezentat si câteva scripturi CGI, fiind convins ca majoritatea cititorilor stiu cum functioneaza si ce sunt de fapt scripturile CGI.

În ultima vreme, politica a devenit un subiect destul de discutat, asa ca am pus un sondaj de opinie într-una dintre paginile întretinute de mine, sub titlul "Cine va câstiga alegerile din 2000?". Sondajul a avut succes - pâna în momentul de fata peste 6000 de persoane si-au exprimat optiunea politica. Dupa putin timp, am primit mai multe scrisori în care persoanele respective mi-au cerut sa le dau programul care sta în spatele acestui sondaj, pentru ca si ei au pagina pe Web si vor sa introduca un sondaj asemanator. Le-am trimis programul, un script gratuit si extrem de usor de configurat.

Au urmat mai multe întrebari de la cei carora le-am trimis programul. Ma întrebau ce trebuie sa faca, pentru ca scriptul nu functioneaza iar în navigator apare sursa programului în loc de ceva inteligibil. Dupa alte câteva scrisori, mi-am dat seama ca putini sunt cei care stiu ce este un script CGI si cum functioneaza acesta. Acest articol îsi propune sa clarifice subiectul în discutie.


Foarte pe scurt

Am început sa învat limbajul Perl pentru ca am vrut sa creez pagini interactive pentru Web. Programele care fac ca Web-ul sa fie dinamic sunt adesea numite "scripturi CGI" pentru ca folosesc o interfata standard, despre care se presupune ca este suportata de toate serverele Web, interfata numita CGI - Common Gateway Interface. (Am spus "se presupune" pentru ca înca nu am întâlnit un server Web care sa nu aiba suport pentru CGI dar, pe de alta parte, nu pot pretinde ca am verificat toate serverele Web existente la ora actuala.) CGI defineste un mediu în care orice proces este rulat de catre serverul de Web. Un proces rulat de server poate fi scris în orice limbaj de programare. Vorbim despre "scripturi CGI" pentru ca de obicei ne este mai usor sa le scriem în limbaje interpretate, numite "limbaje de scripting". Interfata CGI redirecteaza datele de intrare catre un proces rulat de server si intercepteaza datele de iesire ale acestuia. Acest articol va examina interfata CGI si modul cum se integreaza aceste scripturi în sistem.


Protocolul HTTP

Înainte de a urmari modul cum functioneaza un script CGI, trebuie sa ne oprim putin asupra protocolului HTTP (Hypertext Transfer Protocol), care este metoda fundamentala de comunicatie prin Web. Sarcina unui server Web este sa raspunda la o cerere HTTP primita de la client. Daca cererea este pentru un fisier - continând poate cod HTML, o imagine, un film sau sunet - atunci serverul va localiza fisierul si îl va trimite catre client.

HTTP este un protocol text, mesajele fiind alcatuite dintr-o linie initiala - care poate fi o cerere initiata de un navigator (browser) sau o linie de raspuns de la server - urmata de mai multe date. Prin "mai multe date" se poate întelege un fisier, iar tipul informatiei din fisier este specificat folosind conventia adoptata pentru MIME (Multimedia Internet Mail Extension).

MIME a aparut din nevoia de a trimite alte informatii decât text simplu într-o scrisoare electronica. Acest protocol a fost preluat de catre HTTP ca o tehnologie convenabila pentru a trata diferite tipuri de fisiere. Spre deosebire de multe alte protocoale folosite în Internet, HTTP este bidirectional. De exemplu, în marea majoritate a cazurilor, mesajul contine un fisier care va fi trimis clientului de catre server si MIME este folosit de programul client pentru a afla cum sa afiseze fisierul. Desigur, si clientul poate sa trimita un fisier catre server folosind acelasi protocol.


Servere Web

Multe servere Web sunt configurate în asa fel încât atunci când o cerere HTTP de la navigator solicita un fisier cu extensia cgi, fisierul nu va fi trimis. În schimb, serverul va verifica daca programul respectiv este executabil si, în caz afirmativ, va rula programul, despre care se poate presupune ca are sarcina sa genereze date de iesire corespunzatoare. Serverul Web poate fi configurat si în asa fel încât o cerere catre un fisier aflat într-un director anume sa se execute ca un script. Acest director special este numit de obicei cgi-bin.

Serverele Web au adoptat aceste "directoare speciale" din motive de securitate. Este periculos sa permitem utilizatorului Mitica sa lanseze programe pe masina noastra - chiar daca este vorba de propriile noastre programe - deci majoritatea serverelor limiteaza accesul la scripturile CGI. Este un obicei bun sa ascundem scripturile în asa fel încât acestea sa fie executabile, dar sa nu poata fi descarcate. Eu de obicei pun scripturile în afara directoarelor din care se pot descarca fisiere.

Desigur, ascunderea scripturilor nu ne asigura o securitate maxima, deoarece prietenul apropiat al lui Mitica, George Distrugatorul, poate sa analizeze scripturile si sa gaseasca gauri de securitate în acestea.


Schimbul de informatii

Când scriem scripturi CGI, cream de fapt un program care va rula ca un subproces al serverului Web. Trebuie sa gasim o modalitate pentru ca scriptul nostru sa primeasca informatii de la server. Exista câteva metode care sunt folosite pentru a transmite informatiile catre scriptul care ruleaza. Prima modalitate la care ma gândesc este folosirea parametrilor. De fapt, scripturile CGI nu folosesc parametri asa cum sunt folositi în alte programe, poate pentru ca aceasta modalitate a fost considerata "prea UNIX", sau pentru ca standardele pentru transmiterea de parametri catre programe sunt prea restrictive.

A doua metoda de a transmite date catre procesul fiu este prin "variabile de mediu": o serie de perechi de forma nume=valoare sunt mostenite de procesul fiu de la parinte în momentul în care procesul fiu este creat. UNIX foloseste de obicei variabile de mediu pentru a pastra informatiile utile în context global, punându-le astfel la dispozitia proceselor.

Structura nume=valoare a variabilelor de mediu se potriveste foarte bine cu datele care vin din formularul (form) pe care utilizatorul l-a încarcat în navigator. Fiecarui câmp de intrare de pe formular poarta un nume si va primi si o valoare furnizata de catre utilizator. Valoarea trebuie sa fie legata de numele câmpului si perechea sa fie trimisa serverului Web.

În fine, o alta metoda de a trimite date catre procesul fiu este sa scriem informatiile într-un fisier si sa specificam procesului fiu sa citeasca datele din acesta. Aceasta tehnica este frecvent utilizata în redirectarea de tip shell. De exemplu, comanda:

$ ls-l /bin | more

va determina shell-ul sa lanseze comanda ls si sa redirecteze rezultatul comenzii catre o intrare standard a comenzii more. Comanda more primeste de fapt un descriptor al unui fisier deschis, din care sa citeasca datele.


Variabile de mediu

Când un client trimite serverului Web o cerere care are drept rezultat executia unui script, serverul va preîncarca mai multe variabile de mediu, pe care scriptul CGI le va mosteni si pe care le va putea consulta. Anumite variabile de mediu sunt considerate parti "standard " ale protocolului CGI. Serverul poate sa defineasca si alte variabile de mediu. Eu folosesc des un script CGI de tip shell simplu, care contine comanda set pentru a vedea variabilele de mediu care sunt returnate de server, de obicei pentru a verifica daca stiu denumirea corecta a unei anumite variabile (vezi mai jos).

Nu voi enumera variabilele aici, dar voi vorbi despre ele în general. Aceste variabile pot fi împartite în trei categorii.

În primul rând, sunt variabile care comunica scriptului date despre serverul pe care ruleaza. De exemplu, scriptul poate afla numarul portului pe care îl foloseste.
În al doilea rând, sunt si câteva variabile care furnizeaza scriptului informatii de baza despre programul client (de obicei un browser Web) si despre sistemul care a formulat cererea pentru date. Astfel, de exemplu, scriptul poate sa identifice adresa IP a clientului sau tipul navigatorului. Dar pe de alta parte, nu poate identifica nici persoana, nici adresa ei de e-mail.
În al treilea rând, sunt variabile care contin informatii despre tranzactia curenta. Precum am mai spus, HTTP foloseste protocolul MIME pentru a schimba informatii. Tipul MIME este pus la dispozitia scriptului în variabila CONTENT_TYPE.

GET si POST

Exista doua variante de a trimite catre serverul Web informatia culeasa într-un formular care apeleaza un script CGI: GET si POST. Parametrul METHOD specifica alegerea facuta la implementarea formularului în pagina Web. Fiecare metoda foloseste o cale diferita pentru a trimite informatiile din formular la server, în momentul în care butonul submit (trimite) este apasat.

Denumirile GET si POST se refera la comenzi din protocolul HTTP. Când navigatorul cere o pagina obisnuita, trimite o cerere de genul:

GET /main.html HTTP/1.1

Cererea de mai sus îi solicita serverului pagina /main.html si îi indica faptul ca este capabil sa faca fata versiunii 1.1 a protocolului HTTP. Daca totul este ok, atunci serverul va raspunde cu un mesaj care contine datele cerute.

Când navigatorului i se spune sa trimita datele din formular folosind o cerere de tip GET, acesta va trimite cererea adaugând la sfârsitul URL-ului un semn de întrebare si continutul formularului. Se creeaza un URL, extins continând adresa paginii si parametrii care trebuie trimisi scriptului (de exemplu http://www.domeniu.dom/cgi-bin/script.pl?name=John& tel=1274). Daca sunt foarte multe perechi nume = valoare în formular sau daca valorile sunt mari, atunci aceasta cerere initiala catre server poate fi prea mare iar serverul nu îi va putea face fata. La fel, când URL-ul este procesat de server, orice sir de caracter urmat de un semn de întrebare ajunge într-o variabila de mediu (QUERY_STRING), care este pusa la dispozitia scriptului CGI.

Este de dorit sa se limiteze spatiul ocupat de variabilele de mediu. Astfel, pentru formularele mai mari este de preferat metoda POST. În acest caz, datele din formular nu sunt trimise ca parte a URL-ului, ci sub forma unui fisier codat cu standardul MIME înglobat în corpul mesajului trimis catre server. Datorita faptului ca datele sunt trimise codat MIME, serverul stie marimea si tipul datelor si va trece aceste valori în script folosind variabila de mediu CONTENT_LENGTH si CONTENT_TYPE. În plus, scriptul asteapta sa se citeasca setul de parametrii trimis din formular de pe canalul sau standard de intrare. Este de datoria serverului sa asigure ca datele trimise de catre navigator sa fie puse la dispozitia scriptului, gata de a fi importate si scanate pentru perechile nume=valoare.

Exista însa o complicatie atât pentru GET cât si pentru POST. Am amintit ca HTTP este un protocol de tip text si ca folosirea textului pentru a transporta informatii are probleme.

Se întâmpla des ca într-o aplicatie de text sa trebuiasca sa "furam" caractere pentru a le folosi în aplicatia însasi. Gânditi-va la fisierul de parole din UNIX: foloseste caracterul doua puncte (:) pentru a separa diferitele informatii despre utilizator, cum ar fi parola, numele, iar acest lucru înseamna ca nu putem avea un nume de utilizator care sa contina caracterul doua puncte. Se spune ca acesta (caracterul ":") este un caracter "furat".

Pentru a evita acest lucru, protocolul HTTP foloseste o metoda de decodare ca sa asigure faptul ca informatia ramâne intacta în urma transmisiei. Pentru a codifica datele folosite în URL-uri, caracterele spatiu sunt înlocuite cu semnul plus (+) si toate celelalte caractere care nu sunt alfanumerice sunt înlocuite cu semnul procent (%) urmat de codul hexazecimal al caracterului.

Într-un mesaj POST sau GET, datele din formular sunt trimise folosind aceasta metoda de codificare. Numele câmpurilor si valorile sunt codate si fiecare pereche este transformat într-un sir de caractere nume=valoare, aceste siruri de caractere fiind apoi concatenate într-un singur sir, în care perechile sunt separata de caracterul &. De exemplu, un formular cu metoda POST care contine doua variabile NAME si PHONE îsi va trimite data astfel:

NAME=Joe&PHONE=1274

Metoda GET va adauga acest sir de caractere la URL, dupa semnul de întrebare, în timp ce metoda POST va transmite datele ca o parte a protocolului HTTP, urmând ca scriptul sa le citeasca de pe canalul sau standard de intrare.

POST /cgi-bin/script.pl HTTP/1.1

Accept: images/gif, image/x-xbitmap,

image/jpeg, image/pjepeg, */*

Accept-Language: en-us,ro;q=0.5

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0;

Windows 95)

Host: www.domain.com

Content-Length: 41280

Connection: Keep-Alive

Pragma: no-cache

Name=John&tel=1274


Raspunsul dat de script

Datoria serverului Web este de a trimite raspunsuri la cererile clientilor. Scripturile CGI sunt utilizate de regula pentru a colecta date din diverse surse (de obicei baze de date, fisiere locale etc.), a le grupa, a le formata si, în fine, a le trimite clientului care le-a solicitat. Serverul Web aranjeaza lucrurile în asa fel încât iesirea standard a scriptului sa fie redirectionata catre navigatorul clientului. Totusi, datele trimise de catre script trebuie sa fie codificate prin standardul MIME, astfel încât un script trebuie sa porneasca prin trimiterea unui antet (header) MIME care specifica tipul datelor care vor urma, antet care este separat de informatia codata printr-un rând liber. Daca veti examina un script scris în PERL care returneaza o pagina HTML-ul, sunt sanse mari ca acesta sa înceapa o linie de forma:

Print "Content-type:text/html\n\n";

Prin aceasta se specifica faptul ca datele care urmeaza reprezinta cod HTML. Observati ca apare un rând liber în plus dupa aceasta afirmatie, pentru a separa antetul de corpul mesajului. Antetul fiind trimis, scriptul poate sa transmita linistit date de tip HTML.


Un exemplu

Am vorbit mai devreme despre scrierea unui script CGI care sa afiseze toate variabilele de mediu setate de server. Iata cum ar putea arata, ca script CGI shell:

#!/bin/sh

echo 'Content-type: text/plain'

echo

set

Trebuie sa plasati acest script în cgi-bin-ul dumneavoastra si sa îl denumiti - sa zicem - shset. Scriptul este executat de shell. Folosim perechea standard de caractere magice la începutul fisierului ( #!) pentru a comunica sistemului ca acesta este un fisier executabil. Pentru a rula, scriptului trebuie sa-i setam drepturile de executie.

chmod +x shset

Scriptul afiseaza antetul MIME, un rând liber si apoi foloseste comanda standard shell set pentru a afisa valorile mediului. Acum puteti sa-l apelati dintr-un browser Web, prin introducerea unui URL de genul urmator:

http://www.domain.com/cgi-bin/shset

Veti obtine un ecran plin cu informatii care va arata diferite valori care sunt stabilite de serverul dumneavoastra

Deoarece scriptul CGI returneaza o parte din informatiile trimise prin protocolul HTTP catre browser, este usor sa-l determinam sa foloseasca capacitati speciale ale acestuia. De exemplu, se pot crea pagini în care sa spunem: "Multumesc pentru introducerea datelor" si sa instruim navigatorul sa astepte 10 secunde si apoi sa se conecteze la o alta adresa, de exemplu la pagina de intrare a serverului (sau, eventual, la pagina pe care utilizatorul o vizitase înainte sa înceapa sa completeze formularul). Pentru aceasta e suficient adaugati la antetul HTTP un rând ca cel care urmeaza:

Refresh: 10; URL=http://www.domain.com/index.html

Observatie: URL-ul trebuie sa fie o cale absoluta.


Decodarea argumentelor CGI

Spatiul tipografic nu ne permite sa tratam aici detaliile decodarii argumentelor URL. În materialul bibliografic specificat la sfârsitul acestui articol puteti gasi mai multe exemple de scripturi care va vor ajuta la întelegerea acestora. Perl-ul are acum un modul standard (CGI.pm) care usureaza extrem de mult rezolvarea acestor sarcini (vezi Listing 1).

Utilizarea bibliotecilor standard are avantaje si dezavantaje. Pentru programe foarte simple, se întâmpla sa nu folosesc aceste biblioteci, desi bibliotecile rezolva problemele mai usor si ascund partile neplacute ale problemei respective. Astfel, când folositi o biblioteca, probabil nu trebuie sa stiti ce probleme încearca sa rezolve. Daca functioneaza, este perfect. Dar daca nu, gasirea problemei este mai dificila, pentru ca va trebui sa cititi si sa întelegeti codul scris de altcineva. Mai mult, acea persoana a carui cod trebuie sa-l descifrati poate fi un programator experimentat care foloseste structuri Perl care nu sunt asa de evidente.

În sfârsit, daca folositi o biblioteca trebuie sa va supuneti modului în care autorul crede ca trebuie rezolvata problema respectiva. În cazul modulului CGI.pm, acest lucru înseamna ca programul scris de noi va contine codul care genereaza aspectul formularului, codul care parseaza datele din formular, cel care verifica veridicitatea acestora, cât si codul care contine actiunea principala a procesarii formularului. În acest fel, scriptul va contine functii nefolosite (ceea ce-i va creste dimensiunea) iar codul pentru generarea aspectului paginii nu este separat destul de clar de codul pentru actiunea propriu-zisa - de obicei selectarea informatiilor ce trebuie afisate.

De fapt, pentru a citi valorile din formular trimisi trimise prin metoda POST aveti nevoie de vreo 13 linii sursa Perl (vezi Listing 2) si puteti gasi variante ale acestui cod în diverse carti.

În prima faza (linia 3) scriptul citeste câtiva octeti de pe canalul lui standard de intrare, unde serverul Web plaseaza valorile metodei POST. Rutina stie câti octeti trebuie sa citeasca deoarece poate sa examineze variabila de mediu CONTENT_LENGTH. Folosind limbajul Perl, toate variabilele de mediu pot fi interogate folosind vectorul asociativ ENV.

Datele citite sunt stocate într-un sir, care apoi este separat într-un vector folosind ca separator caracterul & (linia 4). Avem acum câteva siruri de caractere de forma nume=valoare de care avem nevoie în continuare. Separam (6) fiecare dintre sirurile de caractere în doua variabile (folosind ca separator caracterul =), dupa care decodificam caracterele modificate (7-8) din valoarea corespunzatoare fiecarui câmp. În cele din urma se depoziteaza (linia 10) argumentele într-un vector asociativ. În final (liniile 12-14), se afiseaza perechile nume = valoare receptionate din formular prin metoda POST.

Pentru cei care nu cunosc Perl: vectorii asociativi sunt structuri de stocare echivalente cu ceea ce în alte limbaje se cheama "tablouri asociative" sau "dictionare". În principiu, sunt structuri similare cu tablourile obisnuite, cu diferenta ca accesarea elementelor se poate face nu doar printr-un index numeric, ci si printr-un alt tip de valoare (de exemplu, sir de caractere), numita "cheie". Astfel, expresia $FORM{"nume"} va furniza valoarea care este asociata sirului "nume" în vectorul asociativ FORM.


Recomandari

- World Wide Web Consortium (W3C) - http://www.w3.org/. .

- The CGI Resource Index - http://cgi.resourceindex.com/.

Péter Csaba lucreaza la firma NetSoft si poate fi contactat prin e-mail la cpeter@netsoft.ro
(Multumiri speciale pentru Nagy Nóra pentru ajutorul acordat în realizarea acestui articol)

Acest articol a aparut in revista PC Report Nr 94 / Iulie 2000
webmaster@pcreport.ro

Nota
Dreptul de autor pentru acest articol apartine in totalitate si in mod exclusiv autorului acestuia .


I HOME I EBUSINESS I WEBDESIGN I EBOOKS I ARTICOLE I HARTA SIT I

COPYRIGHT © 2001 , DAN PAUNESCU , TOATE DREPTURILE REZERVATE