Agora
Media
Libraria Byblos



AgoraNews  





PC Magazine Ro  




NET Report   




Ginfo   




agora ON line   





PC Concrete   





Liste de discuţii   




Cartea de oaspeţi   




Mesaje   





Agora   








Clic aici
PC Report - ultimul numar aparut


IPRO - PC Magazine Romania, Iunie 2003
SOLUŢII PENTRU PROGRAMATORII ŞI DESIGNERII WEB

Librăria libcurl

Konstantin Klyagin

Fiecare programator profesionist ştie ce înseamnă un deadline (dată de predare). Înaintea unui deadline, când nu mai ai timp să scrii ceva, ideal este să găseşti o soluţie deja creată de un alt programator, şi care să se potrivească proiectului tău. În special dacă acea soluţie salvatoare constă într-un cod sursă scris de altcineva şi care se poate folosi pentru a realiza o mare parte din funcţionalităţile care mai trebuiau implementate. Astăzi vă voi prezenta un astfel de caz din propria experienţă. Veţi afla cum lumea Open Source îi poate ajuta pe programatorii care lucrează la dezvoltarea de programe comerciale.

Mai precis, este vorba despre realizarea unui client de HTTP într-un program scris în limbajul de programare C++ pentru Windows. Acel program este dezvoltat de firma la care lucrez, şi, la fel ca restul produselor noastre, este dedicat procesării unor imagini.

Bineînţeles, când se plănuia facilitatea de trimitere a fişierelor grafice către server, fără îndoială a fost ales protocolul HTTP ca fiind cel mai standardizat, sigur şi flexibil dintre cele existente.

Dar degeaba mă aşteptam să găsesc o asemenea funcţie în bibliotecile standard ale lui Visual C++. Este drept că el are clasa HttpClient care poate servi cereri simple (simple request), poate face şi metoda POST, dar pentru a trimite fişiere este nevoie de mai mult şi în particular, de suport pentru conţinut "multipart" şi codare "mime". Din păcate, ultimele două lucruri lipseau punând un semn de întrebare asupra planului nostru luând în considerare şi deadline-urile.

Imediat am pornit o căutare pe google încercand să găsesc ceva deja scris. Câteva minute mai târziu eram la http:// curl.haxx.se/ şi descărcam sursele. Chiar dacă numele curl nu sună prea bine în româneşte, ceea ce am văzut după aceea m-a uimit.

Pachetul conţine un utilitar şi o bibliotecă, utilitarul constând într-o interfaţă gen linie de comandă pentru utilizarea bibliotecii, în care doar cu ajutorul câtorva funcţii simple se poate face aproape orice cu protocoalele internet HTTP, HTTPS, FTP, Gopher, TELNET şi DICT. Printre capacităţile suportate se numără primirea şi transmiterea unor documente cu posibilitatea de a continua de la poziţia unde a fost întrerupt ultimul transfer, suport pentru server-e proxy şi autentificarea cu "login" şi "password". Se poate folosi în programele multithread şi în afară de toate astea, sursele se compilează în Linux, BSD, SunOS, MacOS X, Windows, OpenVMS, IRIX, Tru64, HP-UX, pe toate arhitecturile pe care acestea merg.

Dar haideţi să vedem cum se rezolvă problema de mai sus, folosind biblioteca de funcţii libcurl.

CURL *curl;
CURLcode res;
struct HttpPost *formpost, *lastptr;

formpost = lastptr = NULL;

curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "username",
CURLFORM_COPYCONTENTS, "pamela", CURLFORM_END);

curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "password",
CURLFORM_COPYCONTENTS, "secret", CURLFORM_END);

curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file",
CURLFORM_FILE, "myphoto.jpg", CURLFORM_END);

curl = curl_easy_init();

if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://www.playboy.com/");
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_formfree(formpost);
}

După cum se vede din cod, setarea majorităţii parametrilor iniţiali se face înainte ca cererea (request-ul) să fie executat, cu ajutorul unor apeluri către curl_easy_setopt(), fiecare apel schimbând câte o setare. De exemplu, pentru a citi pagina returnată de server-ul web, se poate ataşa o funcţie callback:

curl_easy_setopt(curl,
CURLOPT_CURLOPT_WRITEFUNCTION, &wfunc);

Write function aici se referă la nevoia bibliotecii de a scrie undeva datele pe care le primeşte de la server, iar funcţia
writefunc are următorul prototip:

size_t wfunc(void *ptr, size_t size, size_t nmemb, void *stream);

Funcţia va fi apelată pentru fiecare pachet de date primit. Exemplul de mai jos ilustrează cum se poate face descărcarea unui fişier de pe un server FTP.

#include <curl/curl.h>

FILE *f;

int ftpwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
if(!f) {
f = fopen("curl.tgz", "wb");
if(!f) return -1;
}

return fwrite(buffer, size, nmemb, f);
}

int main() {
CURL *curl;
CURLcode res;

f = NULL;
curl = curl_easy_init();

if(curl) {
curl_easy_setopt(curl, CURLOPT_URL,
"ftp://ftp.sunet.se/pub/www/utilities/curl/curl-7.10.4.tar.gz");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ftpwrite);
curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

if(f)
fclose(f);

return 0;
}

Setarea opţiunii CURL_VERBOSE vă va da posibilitatea de a vedea cu ce se ocupă la un moment dat biblioteca, pe durata apelului curl_easy_perform().

Vreţi ca o cerere (request) să meargă printr-un server proxy? Poftim, se face prin adăugarea unei singure linii:

curl_easy_setopt(curl,
CURLOPT_PROXY, "http://proxy.my.net:8080/");

Pentru mai multe informaţii legate de opţiunile blibliotecii libcurl uitaţi-vă la pagina man a funcţiei curl_easy_setopt(). Aveţi la dispoziţie 80 de parametri diferiţi ce pot fi setaţi astfel încât să satisfacă orice dorinţe, inclusiv pe cele exotice. Bineînţeles, referitoare doar la executarea unor operaţiuni cu protocoalele internet.

Din exemplele date mai sus vedem că orice protocol dintre cele suportate de curl se poate folosi la fel de uşor, diferenţa între abordări fiind aproape inexistentă. Acest fapt îmi inspiră asociarea cu standardul URL unificat, care permite specificarea locaţiei oricărui document în următorul mod bine cunoscut:

<protocol>://<nume>:<parola>@<server>:<port>/<locatie>

La fel şi libcurl-ul oferă o interfaţă universală pentru accesarea documentelor.
Prin aceasta putem constata că nu este doar o bibliotecă de funcţii, ci o întreagă tehnologie bine gândită, cu ajutorul căreia orice protocol se poate utiliza la fel de uşor.
Biblioteca de funcţii libcurl nu este dedicată exclusiv programatorilor în C ci oferă şi altora posibilitatea de a scrie repede şi uşor programe client. Popularitatea bibliotecii i-a inspirat şi pe cei care utilizează alte limbaje. Ei au creat interfeţe pentru PHP, Perl, Pascal, Basic, Cocoa, Dylan, Euphoria, Java, Lua, Object-Pascal, OCaml, Postgres, Python, Rexx, Ruby, Scheme si Tcl. Spre exemplu, iată cum arată cel mai simplu script PHP care foloseşte libcurl.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://konst.org.ua/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>

Acum a venit momentul să vă ţineţi mai bine de scaune, căci se vor spune câteva cuvinte despre licenţa sub care se distribuie această bibliotecă minunată. Fiind un efort comun al multor oameni care au contribuit la dezvoltarea lui, libcurl este făcut cu scopul ca foarte mulţi dezvoltatori să profite de el, indiferent de genul software-ului pe care îl produc. Fiindcă produsele noastre ca şi cele dezvoltate de majoritatea firmelor de software pentru Windows sunt comerciale, mă temeam că nu-l voi putea folosi datorită licenţei care ar fi putut să nu permită utilizarea bibliotecii la programe de acest gen. Dar ceea ce am găsit în FAQ m-a bucurat foarte mult. Veţi afla imediat de ce.

Conform punctului "License issues" din FAQ, această bibliotecă poate fi folosită la orice fel de proiecte, atât în programe distribuite sub licenţă "free", printre care se numără GPL, LGPL, BSD cât şi în cele comerciale, în cazul cărora codul sursă nu este disponibil. Acest fel de reguli de distribuire se numeşte "Mozilla Public License". Singura restricţie pe care o pune un astfel de licenţă este interdicţia de a modifica textele în sursele care stabilesc drepturile de copiere. Adică nu puteţi schimba numele autorului cu altceva, ceea de, de altfel nici nu este necesar.

Ce să vă mai spun? Acest produs chiar este făcut de programatori pentru pentru programatori. Este evident că un asemenea instrument n-are cum să aibă succes comercial, el nefiind dedicat utilizatorului final, însă în acelaşi timp îi poate ajuta pe mulţi programatori. Până la urmă, faptul că cineva a folosit o biblioteca distribuită gratuit pentru-un produs comercial nu înseamnă neapărat că persoana respectivă n-a contribuit la mişcarea Open Source undeva în altă parte. Foarte mulţi dezvoltatori de software, care crează programare comerciale la servici, în timpul liber contribuie semnificativ la mişcarea GNU şi Open Source.

Exemplul librăriei de funcţii libcurl dovedeşte că cele două feluri de dezvoltare a aplicaţiilor, cel comercial şi cel "Open Source", nu se exclud unul pe celălalt, ci se completează perfect.

Dezvoltarea aplicaţiilor "Open Source" prezintă avantaje atât pentru programatorii de rând care pot folosi munca altor programatori cât şi pentru firme care pot să se concentreze pe dezvoltarea de programe specializate, fără să mai piardă timpul cu rezolvarea unor probleme comune de programare, sau.. chiar mai mult, să trebuiască să cumpere acele soluţii.


PC Magazine Ro | CD ROM | Redactia | Abonamente | CautareArhive

Copyright © 1999-2002 Agora Media.

webmaster@pcmagazine.ro

LG - Life´s Good

deltafri

Concurs de Grafica Digitala si Web Design

www.agora.ro

www.agora.ro