forked from enlightenment/efl
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. SVN revision: 31822
This commit is contained in:
parent
ac9e3d7412
commit
9acabdd1c5
|
@ -76,7 +76,15 @@ extern "C" {
|
|||
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 @@ extern "C" {
|
|||
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 @@ extern "C" {
|
|||
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 @@ extern "C" {
|
|||
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 @@ extern "C" {
|
|||
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 @@ extern "C" {
|
|||
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),
|
||||
|
|
|
@ -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 @@ struct _Ecore_Con_Server
|
|||
#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
|
||||
|
||||
|
|
|
@ -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_url_init(void)
|
|||
{
|
||||
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 @@ ecore_con_url_new(const char *url)
|
|||
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 @@ ecore_con_url_destroy(Ecore_Con_Url *url_con)
|
|||
{
|
||||
#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 @@ EAPI int
|
|||
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 @@ ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url)
|
|||
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 @@ ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *cont
|
|||
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 @@ _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
|
|||
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 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
|||
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 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
|||
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 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue