Enlightenment CVS committal Author : barbieri Project : e17 Module : libs/ecore
Dir : e17/libs/ecore/src/lib/ecore_con Modified Files: Ecore_Con.h ecore_con_private.h ecore_con_url.c Log Message: Ecore_Con fixes and improvements. Bugs: - data buffer we are receiving must be copied, or we could receive garbage in the event handler. - complete event show up before we receive the last data event. Improvements: - Use ECORE_MAGIC. - Status code is no longer curl internal status, but ftp or http return code (More usefull than CURLE_OK). - Add a time condition on requested url (see HTTP code 304). - Add progress events also (should work but not really tested). - Add data_set/data_get. Closes bug #217. Patch by Cedric BAIL. =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/Ecore_Con.h,v retrieving revision 1.27 retrieving revision 1.28 diff -u -3 -r1.27 -r1.28 --- Ecore_Con.h 15 Mar 2007 22:21:26 -0000 1.27 +++ Ecore_Con.h 26 Sep 2007 16:01:04 -0000 1.28 @@ -76,7 +76,15 @@ ECORE_CON_REMOTE_SYSTEM, ECORE_CON_USE_SSL = 16 } Ecore_Con_Type; - + + typedef enum _Ecore_Con_Url_Time + { + ECORE_CON_URL_TIME_NONE = 0, + ECORE_CON_URL_TIME_IFMODSINCE, + ECORE_CON_URL_TIME_IFUNMODSINCE, + ECORE_CON_URL_TIME_LASTMOD + } Ecore_Con_Url_Time; + typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; @@ -85,6 +93,7 @@ typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; + typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress; struct _Ecore_Con_Event_Client_Add { @@ -123,8 +132,8 @@ struct _Ecore_Con_Event_Url_Data { Ecore_Con_Url *url_con; - void *data; int size; + unsigned char data[1]; }; struct _Ecore_Con_Event_Url_Complete @@ -132,7 +141,14 @@ Ecore_Con_Url *url_con; int status; }; - + + struct _Ecore_Con_Event_Url_Progress + { + Ecore_Con_Url *url_con; + double total; + double now; + }; + EAPI extern int ECORE_CON_EVENT_CLIENT_ADD; EAPI extern int ECORE_CON_EVENT_CLIENT_DEL; EAPI extern int ECORE_CON_EVENT_SERVER_ADD; @@ -141,6 +157,8 @@ EAPI extern int ECORE_CON_EVENT_SERVER_DATA; EAPI extern int ECORE_CON_EVENT_URL_DATA; EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; + EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD; + EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD; EAPI int ecore_con_init(void); EAPI int ecore_con_shutdown(void); @@ -171,8 +189,11 @@ EAPI int ecore_con_url_shutdown(void); EAPI Ecore_Con_Url *ecore_con_url_new(const char *url); EAPI void ecore_con_url_destroy(Ecore_Con_Url *url_con); + EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, const void *data); + EAPI void *ecore_con_url_data_get(Ecore_Con_Url *url_con); EAPI int ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url); EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type); + EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm); EAPI int ecore_con_dns_lookup(const char *name, void (*done_cb)(void *data, struct hostent *hostent), =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_private.h,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- ecore_con_private.h 5 Nov 2006 16:49:55 -0000 1.18 +++ ecore_con_private.h 26 Sep 2007 16:01:04 -0000 1.19 @@ -6,6 +6,7 @@ #define ECORE_MAGIC_CON_SERVER 0x77665544 #define ECORE_MAGIC_CON_CLIENT 0x77556677 +#define ECORE_MAGIC_CON_URL 0x77074255 #if USE_OPENSSL #include <openssl/ssl.h> @@ -66,12 +67,18 @@ #ifdef HAVE_CURL struct _Ecore_Con_Url { - /* FIXME: ECORE_MAGIC ? */ - CURL *curl_easy; - char *url; + ECORE_MAGIC; + CURL *curl_easy; struct curl_slist *headers; - Ecore_Fd_Handler *fd_handler; - char active : 1; + char *url; + + Ecore_Con_Url_Time condition; + time_t time; + const void *data; + + Ecore_Fd_Handler *fd_handler; + + unsigned char active : 1; }; #endif =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_url.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -3 -r1.14 -r1.15 --- ecore_con_url.c 25 Jul 2007 17:00:55 -0000 1.14 +++ ecore_con_url.c 26 Sep 2007 16:01:04 -0000 1.15 @@ -44,17 +44,52 @@ static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_url_perform(Ecore_Con_Url *url_con); static size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp); -static void _ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev); -static void _ecore_con_event_url_data_free(void *data __UNUSED__, void *ev); +static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev); static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match); int ECORE_CON_EVENT_URL_DATA = 0; int ECORE_CON_EVENT_URL_COMPLETE = 0; +int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = 0; +int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = 0; static CURLM *curlm = NULL; static Ecore_List *_url_con_list = NULL; static fd_set _current_fd_set; static int init_count = 0; + +struct _little_ecore_con_url_event_s +{ + int type; + void *ev; +}; +typedef struct _little_ecore_con_url_event_s _little_ecore_con_url_event_t; + +static int +_url_complete_idler_cb(void *data) +{ + _little_ecore_con_url_event_t *lev; + + lev = data; + + ecore_event_add(lev->type, lev->ev, _ecore_con_event_url_free, NULL); + free(lev); + + return 0; +} + +static void +_url_complete_push_event(int type, void *ev) +{ + _little_ecore_con_url_event_t *lev; + + lev = malloc(sizeof (_little_ecore_con_url_event_t)); + lev->type = type; + lev->ev = ev; + + ecore_idler_add(_url_complete_idler_cb, lev); +} + #endif EAPI int @@ -65,6 +100,8 @@ { ECORE_CON_EVENT_URL_DATA = ecore_event_type_new(); ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new(); + ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = ecore_event_type_new(); + ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = ecore_event_type_new(); } if (!_url_con_list) @@ -149,11 +186,18 @@ free(url_con); return NULL; } - + + ECORE_MAGIC_SET(url_con, ECORE_MAGIC_CON_URL); + ecore_con_url_url_set(url_con, url); curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION, _ecore_con_url_data_cb); curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con); + + curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, _ecore_con_url_progress_cb); + curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSDATA, url_con); + curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, FALSE); + /* * FIXME: Check that these timeouts are sensible defaults * FIXME: Provide a means to change these timeouts @@ -174,7 +218,13 @@ { #ifdef HAVE_CURL if (!url_con) return; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_destroy"); + return ; + } + ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); if (url_con->fd_handler) ecore_main_fd_handler_del(url_con->fd_handler); if (url_con->curl_easy) @@ -195,6 +245,12 @@ ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url) { #ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_url_set"); + return 0; + } + if (url_con->active) return 0; free(url_con->url); @@ -209,12 +265,74 @@ return 1; } +EAPI void +ecore_con_url_data_set(Ecore_Con_Url *url_con, const void *data) +{ +#ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_set"); + return ; + } + + url_con->data = data; +#else + (void*) url_con; + (const void*) data; + + return ; +#endif +} + +EAPI void* +ecore_con_url_data_get(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_get"); + return NULL; + } + + return (void*) url_con->data; +#else + (void*) url_con; + + return NULL; +#endif +} + +EAPI void +ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm) +{ +#ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_time"); + return ; + } + + url_con->condition = condition; + url_con->time = tm; +#else + (void*) url_con; + condition; + tm; +#endif +} + EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type) { #ifdef HAVE_CURL char tmp[256]; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send"); + return 0; + } + if (url_con->active) return 0; if (!url_con->url) return 0; @@ -235,6 +353,25 @@ url_con->headers = curl_slist_append(url_con->headers, tmp); } + switch (url_con->condition) + { + case ECORE_CON_URL_TIME_NONE: + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE); + break; + case ECORE_CON_URL_TIME_IFMODSINCE: + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time); + break; + case ECORE_CON_URL_TIME_IFUNMODSINCE: + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFUNMODSINCE); + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time); + break; + case ECORE_CON_URL_TIME_LASTMOD: + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, CURL_TIMECOND_LASTMOD); + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time); + break; + } + curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers); return _ecore_con_url_perform(url_con); @@ -256,24 +393,45 @@ size_t real_size = size * nmemb; url_con = (Ecore_Con_Url *)userp; - e = calloc(1, sizeof(Ecore_Con_Event_Url_Data)); + e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1)); if (e) { e->url_con = url_con; - e->data = buffer; e->size = real_size; + memcpy(e->data, buffer, real_size); ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, - _ecore_con_event_url_data_free, NULL); + _ecore_con_event_url_free, NULL); } return real_size; } -/* - * FIXME: Use - * CURLOPT_PROGRESSFUNCTION and CURLOPT_PROGRESSDATA to - * get reports on progress. - * And maybe other nifty functions... - */ +#define ECORE_CON_URL_TRANSMISSION(Transmit, Event, Url_con, Total, Now) \ + { \ + Ecore_Con_Event_Url_Progress *e; \ + if (Total != 0 || Now != 0) { \ + e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); \ + if (e) { \ + e->url_con = url_con; \ + e->total = Total; \ + e->now = Now; \ + ecore_event_add(Event, e, _ecore_con_event_url_free, NULL); \ + } \ + } \ + } + +static int +_ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + Ecore_Con_Url *url_con; + + url_con = clientp; + + ECORE_CON_URL_TRANSMISSION(Download, ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD, url_con, dltotal, dlnow); + ECORE_CON_URL_TRANSMISSION(Upload, ECORE_CON_EVENT_URL_PROGRESS_UPLOAD, url_con, ultotal, ulnow); + + return 0; +} + static int _ecore_con_url_perform(Ecore_Con_Url *url_con) { @@ -373,7 +531,6 @@ url_con->fd_handler = NULL; } ecore_list_remove(_url_con_list); - curl_multi_remove_handle(curlm, url_con->curl_easy); url_con->active = 0; { Ecore_Con_Event_Url_Complete *e; @@ -381,11 +538,14 @@ if (e) { e->url_con = url_con; - e->status = curlmsg->data.result; - ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, - _ecore_con_event_url_complete_free, NULL); + + e->status = 0; + curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &e->status); + + _url_complete_push_event(ECORE_CON_EVENT_URL_COMPLETE, e); } } + curl_multi_remove_handle(curlm, url_con->curl_easy); break; } ecore_list_next(_url_con_list); @@ -394,20 +554,9 @@ return job_matched; } static void -_ecore_con_event_url_data_free(void *data __UNUSED__, void *ev) +_ecore_con_event_url_free(void *data __UNUSED__, void *ev) { - Ecore_Con_Event_Url_Data *e; - - e = ev; - free(e); + free(ev); } -static void -_ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev) -{ - Ecore_Con_Event_Url_Complete *e; - - e = ev; - free(e); -} #endif ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs