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.

[email protected]

LG - LifeŽs Good

deltafri

Concurs de Grafica Digitala si Web Design

www.agora.ro

www.agora.ro