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

Reply via email to