fix current url implementation to not crash ANY TIME YOU FREE THE OBJECT DURING AN EVENT

seriously how did this go unnoticed for so many years?????


SVN revision: 68132
This commit is contained in:
Mike Blumenkrantz 2012-02-19 23:16:50 +00:00
parent abd9e9ff4b
commit a8e95378d8
2 changed files with 126 additions and 128 deletions

View File

@ -218,6 +218,9 @@ struct _Ecore_Con_Url
int received; int received;
int write_fd; int write_fd;
unsigned int event_count;
Eina_Bool dead : 1;
}; };
#endif #endif

View File

@ -35,6 +35,8 @@ int ECORE_CON_EVENT_URL_COMPLETE = 0;
int ECORE_CON_EVENT_URL_PROGRESS = 0; int ECORE_CON_EVENT_URL_PROGRESS = 0;
#ifdef HAVE_CURL #ifdef HAVE_CURL
static void _ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg);
static void _ecore_con_url_multi_remove(Ecore_Con_Url *url_con);
static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con); static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con);
static size_t _ecore_con_url_header_cb(void *ptr, static size_t _ecore_con_url_header_cb(void *ptr,
size_t size, size_t size,
@ -53,10 +55,9 @@ static size_t _ecore_con_url_read_cb(void *ptr,
size_t size, size_t size,
size_t nitems, size_t nitems,
void *stream); void *stream);
static void _ecore_con_event_url_free(void *data __UNUSED__, static void _ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev);
void *ev);
static Eina_Bool _ecore_con_url_idler_handler(void *data); static Eina_Bool _ecore_con_url_idler_handler(void *data);
static Eina_Bool _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__); static Eina_Bool _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
static Eina_Bool _ecore_con_url_timeout_cb(void *data); static Eina_Bool _ecore_con_url_timeout_cb(void *data);
static Eina_List *_url_con_list = NULL; static Eina_List *_url_con_list = NULL;
@ -144,10 +145,8 @@ EAPI void
ecore_con_url_pipeline_set(Eina_Bool enable) ecore_con_url_pipeline_set(Eina_Bool enable)
{ {
#ifdef HAVE_CURL #ifdef HAVE_CURL
if (enable) if (enable == pipelining) return;
curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, 1); curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, !!enable);
else
curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, 0);
pipelining = enable; pipelining = enable;
#else #else
return; return;
@ -290,10 +289,8 @@ ecore_con_url_free(Ecore_Con_Url *url_con)
{ {
#ifdef HAVE_CURL #ifdef HAVE_CURL
char *s; char *s;
CURLMcode ret;
if (!url_con) if (!url_con) return;
return;
if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
{ {
@ -301,24 +298,23 @@ ecore_con_url_free(Ecore_Con_Url *url_con)
return; return;
} }
ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
if (url_con->curl_easy) if (url_con->curl_easy)
{ {
curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL); curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL);
curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE); curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE);
if (eina_list_data_find(_url_con_list, url_con)) _ecore_con_url_multi_remove(url_con);
{ _url_con_list = eina_list_remove(_url_con_list, url_con);
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
_url_con_list = eina_list_remove(_url_con_list, url_con);
}
curl_easy_cleanup(url_con->curl_easy); curl_easy_cleanup(url_con->curl_easy);
} }
if (url_con->timer) ecore_timer_del(url_con->timer); if (url_con->timer) ecore_timer_del(url_con->timer);
url_con->curl_easy = NULL;
url_con->timer = NULL;
if (url_con->event_count) return;
ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
curl_slist_free_all(url_con->headers); curl_slist_free_all(url_con->headers);
EINA_LIST_FREE(url_con->additional_headers, s) EINA_LIST_FREE(url_con->additional_headers, s)
free(s); free(s);
@ -360,8 +356,7 @@ ecore_con_url_url_set(Ecore_Con_Url *url_con,
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE; if (url_con->dead) return EINA_FALSE;
eina_stringshare_replace(&url_con->url, url); eina_stringshare_replace(&url_con->url, url);
if (url_con->url) if (url_con->url)
@ -405,6 +400,7 @@ ecore_con_url_additional_header_add(Ecore_Con_Url *url_con,
#ifdef HAVE_CURL #ifdef HAVE_CURL
char *tmp; char *tmp;
if (url_con->dead) return;
if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
{ {
ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
@ -412,6 +408,7 @@ ecore_con_url_additional_header_add(Ecore_Con_Url *url_con,
return; return;
} }
if (url_con->dead) return;
tmp = malloc(strlen(key) + strlen(value) + 3); tmp = malloc(strlen(key) + strlen(value) + 3);
if (!tmp) if (!tmp)
return; return;
@ -477,6 +474,7 @@ ecore_con_url_time(Ecore_Con_Url *url_con,
return; return;
} }
if (url_con->dead) return;
url_con->time_condition = condition; url_con->time_condition = condition;
url_con->timestamp = timestamp; url_con->timestamp = timestamp;
#else #else
@ -498,6 +496,7 @@ ecore_con_url_fd_set(Ecore_Con_Url *url_con,
return; return;
} }
if (url_con->dead) return;
url_con->write_fd = fd; url_con->write_fd = fd;
#else #else
return; return;
@ -551,6 +550,7 @@ ecore_con_url_httpauth_set(Ecore_Con_Url *url_con,
return EINA_FALSE; return EINA_FALSE;
} }
if (url_con->dead) return EINA_FALSE;
# if LIBCURL_VERSION_NUM >= 0x071301 # if LIBCURL_VERSION_NUM >= 0x071301
if ((username) && (password)) if ((username) && (password))
{ {
@ -612,10 +612,8 @@ _ecore_con_url_send(Ecore_Con_Url *url_con,
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE; if (!url_con->url) return EINA_FALSE;
if (url_con->dead) return EINA_FALSE;
if (!url_con->url)
return EINA_FALSE;
/* Free response headers from previous send() calls */ /* Free response headers from previous send() calls */
EINA_LIST_FREE(url_con->response_headers, s) EINA_LIST_FREE(url_con->response_headers, s)
@ -736,56 +734,52 @@ ecore_con_url_ftp_upload(Ecore_Con_Url *url_con,
ECORE_MAGIC_CON_URL, ECORE_MAGIC_CON_URL,
"ecore_con_url_ftp_upload"); "ecore_con_url_ftp_upload");
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE; if (url_con->dead) return EINA_FALSE;
if (!url_con->url) return EINA_FALSE;
if ((!filename) || (!filename[0])) return EINA_FALSE;
if (!url_con->url) if (stat(filename, &file_info))
return EINA_FALSE; return EINA_FALSE;
if (filename) snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass);
ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd);
if (ret != CURLE_OK)
{ {
if (stat(filename, &file_info)) ERR("Could not set username and password for FTP upload: %s",
return EINA_FALSE; curl_easy_strerror(ret));
return EINA_FALSE;
snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass);
ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd);
if (ret != CURLE_OK)
{
ERR("Could not set username and password for FTP upload: %s",
curl_easy_strerror(ret));
return EINA_FALSE;
}
char tmp[PATH_MAX];
snprintf(tmp, PATH_MAX, "%s", filename);
if (upload_dir)
snprintf(url, sizeof(url), "ftp://%s/%s/%s", url_con->url,
upload_dir, basename(tmp));
else
snprintf(url, sizeof(url), "ftp://%s/%s", url_con->url,
basename(tmp));
if (!ecore_con_url_url_set(url_con, url))
return EINA_FALSE;
curl_easy_setopt(url_con->curl_easy, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
curl_easy_setopt(url_con->curl_easy, CURLOPT_UPLOAD, 1);
curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION,
_ecore_con_url_read_cb);
fd = fopen(filename, "rb");
if (!fd)
{
ERR("Could not open \"%s\" for FTP upload", filename);
return EINA_FALSE;
}
curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd);
return _ecore_con_url_perform(url_con);
} }
char tmp[PATH_MAX];
snprintf(tmp, PATH_MAX, "%s", filename);
if (upload_dir)
snprintf(url, sizeof(url), "ftp://%s/%s/%s", url_con->url,
upload_dir, basename(tmp));
else
snprintf(url, sizeof(url), "ftp://%s/%s", url_con->url,
basename(tmp));
if (!ecore_con_url_url_set(url_con, url))
return EINA_FALSE;
curl_easy_setopt(url_con->curl_easy, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
curl_easy_setopt(url_con->curl_easy, CURLOPT_UPLOAD, 1);
curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION,
_ecore_con_url_read_cb);
fd = fopen(filename, "rb");
if (!fd)
{
ERR("Could not open \"%s\" for FTP upload", filename);
return EINA_FALSE;
}
curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd);
return _ecore_con_url_perform(url_con);
#else #else
return EINA_FALSE; return EINA_FALSE;
(void)url_con; (void)url_con;
@ -794,8 +788,6 @@ ecore_con_url_ftp_upload(Ecore_Con_Url *url_con,
(void)pass; (void)pass;
(void)upload_dir; (void)upload_dir;
#endif #endif
return EINA_FALSE;
} }
EAPI void EAPI void
@ -812,6 +804,7 @@ ecore_con_url_cookies_init(Ecore_Con_Url *url_con)
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, "");
#else #else
return; return;
@ -833,6 +826,7 @@ ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool i
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore);
#else #else
return; return;
@ -855,6 +849,7 @@ ecore_con_url_cookies_clear(Ecore_Con_Url *url_con)
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL"); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL");
#else #else
return; return;
@ -876,6 +871,7 @@ ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con)
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS"); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS");
#else #else
return; return;
@ -897,6 +893,7 @@ ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char * const file_n
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name);
#else #else
return; return;
@ -921,6 +918,7 @@ ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char * const co
return EINA_FALSE; return EINA_FALSE;
} }
if (url_con->dead) return EINA_FALSE;
ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR, ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR,
cookiejar_file); cookiejar_file);
if (ret != CURLE_OK) if (ret != CURLE_OK)
@ -952,6 +950,7 @@ ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con)
return; return;
} }
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH"); curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH");
#else #else
return; return;
@ -971,11 +970,10 @@ ecore_con_url_verbose_set(Ecore_Con_Url *url_con,
return; return;
} }
if (eina_list_data_find(_url_con_list, url_con)) return;
if (!url_con->url) if (!url_con->url)
return; return;
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose); curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose);
#else #else
return; return;
@ -996,11 +994,10 @@ ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con,
return; return;
} }
if (eina_list_data_find(_url_con_list, url_con)) return;
if (!url_con->url) if (!url_con->url)
return; return;
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv); curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv);
#else #else
return; return;
@ -1033,11 +1030,10 @@ ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con,
return; return;
} }
if (eina_list_data_find(_url_con_list, url_con)) return;
if (!url_con->url) if (!url_con->url)
return; return;
if (url_con->dead) return;
curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify); curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify);
#else #else
return; return;
@ -1076,8 +1072,8 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
return -1; return -1;
} }
if (eina_list_data_find(_url_con_list, url_con)) return -1;
if (!url_con->url) return -1; if (!url_con->url) return -1;
if (url_con->dead) return -1;
if (ca_path == NULL) if (ca_path == NULL)
res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0); res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0);
else else
@ -1105,6 +1101,7 @@ ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Versio
ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_version_set"); ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_version_set");
return EINA_FALSE; return EINA_FALSE;
} }
if (url_con->dead) return EINA_FALSE;
switch (version) switch (version)
{ {
case ECORE_CON_URL_HTTP_VERSION_1_0: case ECORE_CON_URL_HTTP_VERSION_1_0:
@ -1146,8 +1143,8 @@ ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy)
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
if (!url_con->url) return EINA_FALSE; if (!url_con->url) return EINA_FALSE;
if (url_con->dead) return EINA_FALSE;
if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, ""); if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, "");
else else
@ -1196,7 +1193,7 @@ ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout)
return; return;
} }
if (eina_list_data_find(_url_con_list, url_con)) return; if (url_con->dead) return;
if (!url_con->url || timeout < 0) return; if (!url_con->url || timeout < 0) return;
if (url_con->timer) ecore_timer_del(url_con->timer); if (url_con->timer) ecore_timer_del(url_con->timer);
url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con); url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con);
@ -1218,9 +1215,9 @@ ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username)
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE; if (url_con->dead) return EINA_FALSE;
if (!url_con->url) return EINA_FALSE; if (!url_con->url) return EINA_FALSE;
if (!username) return EINA_FALSE; if ((!username) || (!username[0])) return EINA_FALSE;
if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
{ {
ERR("Proxy type should be socks5 and above"); ERR("Proxy type should be socks5 and above");
@ -1251,8 +1248,8 @@ ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password)
ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set"); ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set");
return EINA_FALSE; return EINA_FALSE;
} }
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
if (!url_con->url) return EINA_FALSE; if (!url_con->url) return EINA_FALSE;
if (url_con->dead) return EINA_FALSE;
if (!password) return EINA_FALSE; if (!password) return EINA_FALSE;
if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
{ {
@ -1279,19 +1276,47 @@ ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password)
*/ */
#ifdef HAVE_CURL #ifdef HAVE_CURL
static void
_ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg)
{
Ecore_Con_Event_Url_Complete *e;
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
if (!e) return;
if (curlmsg && (curlmsg->data.result == CURLE_OK))
{
long status; /* curl API uses long, not int */
status = 0;
curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
e->status = status;
}
e->url_con = url_con;
e->status = 0;
url_con->event_count++;
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
}
static void
_ecore_con_url_multi_remove(Ecore_Con_Url *url_con)
{
CURLMcode ret;
if (url_con->dead) return;
url_con->dead = EINA_TRUE;
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
}
static Eina_Bool static Eina_Bool
_ecore_con_url_timeout_cb(void *data) _ecore_con_url_timeout_cb(void *data)
{ {
Ecore_Con_Url *url_con = data; Ecore_Con_Url *url_con = data;
CURLMcode ret;
Ecore_Con_Event_Url_Complete *e;
if (!url_con) return ECORE_CALLBACK_CANCEL; if (!url_con) return ECORE_CALLBACK_CANCEL;
if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL; if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL;
if (!eina_list_data_find(_url_con_list, url_con)) return ECORE_CALLBACK_CANCEL;
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); _ecore_con_url_multi_remove(url_con);
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
_url_con_list = eina_list_remove(_url_con_list, url_con); _url_con_list = eina_list_remove(_url_con_list, url_con);
curl_slist_free_all(url_con->headers); curl_slist_free_all(url_con->headers);
@ -1299,13 +1324,7 @@ _ecore_con_url_timeout_cb(void *data)
url_con->timer = NULL; url_con->timer = NULL;
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); _ecore_con_url_event_url_complete(url_con, NULL);
if (e)
{
e->url_con = url_con;
e->status = 0;
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
}
return ECORE_CALLBACK_CANCEL; return ECORE_CALLBACK_CANCEL;
} }
@ -1343,7 +1362,8 @@ _ecore_con_url_data_cb(void *buffer,
e->url_con = url_con; e->url_con = url_con;
e->size = real_size; e->size = real_size;
memcpy(e->data, buffer, real_size); memcpy(e->data, buffer, real_size);
ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, _ecore_con_event_url_free, NULL); url_con->event_count++;
ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
} }
} }
else else
@ -1415,7 +1435,8 @@ _ecore_con_url_progress_cb(void *clientp,
e->down.now = dlnow; e->down.now = dlnow;
e->up.total = ultotal; e->up.total = ultotal;
e->up.now = ulnow; e->up.now = ulnow;
ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, _ecore_con_event_url_free, NULL); url_con->event_count++;
ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
} }
return 0; return 0;
@ -1458,8 +1479,6 @@ _ecore_con_url_info_read(void)
{ {
Eina_List *l; Eina_List *l;
Ecore_Con_Url *url_con = NULL; Ecore_Con_Url *url_con = NULL;
CURLMcode ret;
Ecore_Con_Event_Url_Complete *e;
if (curlmsg->msg != CURLMSG_DONE) continue; if (curlmsg->msg != CURLMSG_DONE) continue;
@ -1470,23 +1489,8 @@ _ecore_con_url_info_read(void)
} }
if ((!url_con) || (curlmsg->easy_handle != url_con->curl_easy)) continue; if ((!url_con) || (curlmsg->easy_handle != url_con->curl_easy)) continue;
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); _ecore_con_url_event_url_complete(url_con, curlmsg);
if (e) _ecore_con_url_multi_remove(url_con);
{
e->url_con = url_con;
e->status = 0;
if (curlmsg->data.result == CURLE_OK)
{
long status; /* curl API uses long, not int */
status = 0;
curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
e->status = status;
}
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
}
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
_url_con_list = eina_list_remove_list(_url_con_list, l); _url_con_list = eina_list_remove_list(_url_con_list, l);
} }
} }
@ -1512,18 +1516,7 @@ _ecore_con_url_curl_clear(void)
EINA_LIST_FREE(_url_con_list, url_con) EINA_LIST_FREE(_url_con_list, url_con)
{ {
CURLMcode ret;
Ecore_Con_Event_Url_Complete *e;
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
if (e)
{
e->url_con = url_con;
e->status = 0;
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
}
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
} }
} }
@ -1639,10 +1632,12 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
} }
static void static void
_ecore_con_event_url_free(void *data __UNUSED__, _ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev)
void *ev)
{ {
free(ev); free(ev);
url_con->event_count--;
if (url_con->dead && (!url_con->event_count))
ecore_con_url_free(url_con);
} }
#endif #endif