barbieri pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=3cf20ea8e8b9ddcca73578a59442da1c8bf546c5

commit 3cf20ea8e8b9ddcca73578a59442da1c8bf546c5
Author: Gustavo Sverzut Barbieri <[email protected]>
Date:   Tue Nov 29 01:19:40 2016 -0200

    efl_net_dialer_http: special headers and date parse/serialize.
    
    CURL needs some special curl_easy_setopt() calls to enable automatic
    gzip deflate (CURLOPT_ENCODING) and
    If-Modified-Since/If-Unmodified-Since logic.
    
    As If-Modified-Since/If-Unmodified-Since requires a timestamp string,
    let's expose class methods to handle those.
---
 src/lib/ecore_con/ecore_con_url_curl.c   |   1 +
 src/lib/ecore_con/ecore_con_url_curl.h   |   5 ++
 src/lib/ecore_con/efl_net_dialer_http.c  | 103 +++++++++++++++++++++++++++++++
 src/lib/ecore_con/efl_net_dialer_http.eo |  23 +++++++
 4 files changed, 132 insertions(+)

diff --git a/src/lib/ecore_con/ecore_con_url_curl.c 
b/src/lib/ecore_con/ecore_con_url_curl.c
index c6ef501..507dd61 100644
--- a/src/lib/ecore_con/ecore_con_url_curl.c
+++ b/src/lib/ecore_con/ecore_con_url_curl.c
@@ -312,6 +312,7 @@ _c_init(void)
    SYM(curl_slist_free_all);
    SYM(curl_slist_append);
    SYM(curl_version_info);
+   SYM(curl_getdate);
 
    _c_init_errors();
 
diff --git a/src/lib/ecore_con/ecore_con_url_curl.h 
b/src/lib/ecore_con/ecore_con_url_curl.h
index 9f82230..094c286 100644
--- a/src/lib/ecore_con/ecore_con_url_curl.h
+++ b/src/lib/ecore_con/ecore_con_url_curl.h
@@ -446,6 +446,7 @@ struct _Ecore_Con_Curl
    void                    (*curl_slist_free_all)(struct curl_slist *);
    struct curl_slist      *(*curl_slist_append)(struct curl_slist *list,
                                                 const char *string);
+   time_t                  (*curl_getdate)(const char *p, const time_t 
*unused);
    curl_version_info_data *(*curl_version_info)(CURLversion);
 };
 
@@ -460,4 +461,8 @@ void _c_shutdown(void);
 Eina_Error _curlcode_to_eina_error(const CURLcode code);
 Eina_Error _curlmcode_to_eina_error(const CURLMcode code);
 
+
+/* only for legacy support to implement behavior that we're not exposing 
anymore */
+CURL *efl_net_dialer_http_curl_get(const Eo *o);
+
 #endif
diff --git a/src/lib/ecore_con/efl_net_dialer_http.c 
b/src/lib/ecore_con/efl_net_dialer_http.c
index 97b6e5b..cf6c4a9 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.c
+++ b/src/lib/ecore_con/efl_net_dialer_http.c
@@ -29,6 +29,7 @@
 #define curl_easy_init(...) _c->curl_easy_init(__VA_ARGS__)
 #define curl_easy_cleanup(...) _c->curl_easy_cleanup(__VA_ARGS__)
 #define curl_easy_pause(...) _c->curl_easy_pause(__VA_ARGS__)
+#define curl_getdate(s, unused) _c->curl_getdate(s, unused)
 
 #ifdef curl_easy_setopt
 #undef curl_easy_setopt
@@ -1260,6 +1261,7 @@ _efl_net_dialer_http_libproxy_cancel(void *data, 
Ecore_Thread *thread EINA_UNUSE
 EOLIAN static Eina_Error
 _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, 
const char *address)
 {
+   struct curl_slist *sl_it;
    CURLcode r;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(address, EINVAL);
@@ -1279,6 +1281,77 @@ _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, 
Efl_Net_Dialer_Http_Data *pd, co
             o, curl_easy_strerror(r));
         return EINVAL;
      }
+   for (sl_it = pd->request.headers; sl_it != NULL; sl_it = sl_it->next)
+     {
+#define IS_HEADER(x) (strncasecmp(sl_it->data, x ":", strlen(x ":")) == 0)
+        if (IS_HEADER("Accept-Encoding"))
+          {
+             const char *value = strchr(sl_it->data, ':') + 1;
+             while (*value && isspace(*value))
+               value++;
+             r = curl_easy_setopt(pd->easy, CURLOPT_ENCODING, value);
+             if (r != CURLE_OK)
+               {
+                  ERR("dialer=%p could not set HTTP Accept-Encoding '%s': %s",
+                      o, value, curl_easy_strerror(r));
+                  return EINVAL;
+               }
+             DBG("Using Accept-Encoding: %s", value);
+          }
+        else if (IS_HEADER("If-Modified-Since"))
+          {
+             const char *value = strchr(sl_it->data, ':') + 1;
+             long t;
+
+             r = curl_easy_setopt(pd->easy, CURLOPT_TIMECONDITION, 
CURL_TIMECOND_IFMODSINCE);
+             if (r != CURLE_OK)
+               {
+                  ERR("dialer=%p could not set HTTP If-Modified-Since 
condition: %s",
+                      o, curl_easy_strerror(r));
+                  return EINVAL;
+               }
+
+             while (*value && isspace(*value))
+               value++;
+             t = curl_getdate(value, NULL);
+
+             r = curl_easy_setopt(pd->easy, CURLOPT_TIMEVALUE, t);
+             if (r != CURLE_OK)
+               {
+                  ERR("dialer=%p could not set HTTP If-Modified-Since 
value=%ld: %s",
+                      o, t, curl_easy_strerror(r));
+                  return EINVAL;
+               }
+             DBG("Using If-Modified-Since: %s [t=%ld]", value, t);
+          }
+        else if (IS_HEADER("If-Unmodified-Since"))
+          {
+             const char *value = strchr(sl_it->data, ':') + 1;
+             long t;
+
+             r = curl_easy_setopt(pd->easy, CURLOPT_TIMECONDITION, 
CURL_TIMECOND_IFUNMODSINCE);
+             if (r != CURLE_OK)
+               {
+                  ERR("dialer=%p could not set HTTP If-Unmodified-Since 
condition: %s",
+                      o, curl_easy_strerror(r));
+                  return EINVAL;
+               }
+
+             while (*value && isspace(*value))
+               value++;
+             t = curl_getdate(value, NULL);
+
+             r = curl_easy_setopt(pd->easy, CURLOPT_TIMEVALUE, t);
+             if (r != CURLE_OK)
+               {
+                  ERR("dialer=%p could not set HTTP If-Unmodified-Since 
value=%ld: %s",
+                      o, t, curl_easy_strerror(r));
+                  return EINVAL;
+               }
+             DBG("Using If-Unmodified-Since: %s [t=%ld]", value, t);
+          }
+#undef IS_HEADER
+     }
 
    if ((!pd->proxy) && (ecore_con_libproxy_init()))
      {
@@ -2192,6 +2265,36 @@ _efl_net_dialer_http_cookie_jar_get(Eo *o EINA_UNUSED, 
Efl_Net_Dialer_Http_Data
    return pd->cookie_jar;
 }
 
+EOLIAN static long
+_efl_net_dialer_http_date_parse(Efl_Class *cls EINA_UNUSED, void *cd 
EINA_UNUSED, const char *str)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(str, 0);
+   return curl_getdate(str, NULL);
+}
+
+EOLIAN static char *
+_efl_net_dialer_http_date_serialize(Efl_Class *cls EINA_UNUSED, void *cd 
EINA_UNUSED, long t)
+{
+   static const char *const wkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", 
"Fri", "Sat" };
+   static const char * const month[] = { "Jan", "Feb", "Mar", "Apr", "May", 
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+   char buf[128];
+   struct tm *tm, storage;
+
+   tm = gmtime_r(&t, &storage);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(tm, NULL);
+
+   snprintf(buf, sizeof(buf),
+            "%s, %02d %s %4d %02d:%02d:%02d GMT",
+            wkday[tm->tm_wday],
+            tm->tm_mday,
+            month[tm->tm_mon],
+            tm->tm_year + 1900,
+            tm->tm_hour,
+            tm->tm_min,
+            tm->tm_sec);
+   return strdup(buf);
+}
+
 CURL *
 efl_net_dialer_http_curl_get(const Eo *o)
 {
diff --git a/src/lib/ecore_con/efl_net_dialer_http.eo 
b/src/lib/ecore_con/efl_net_dialer_http.eo
index f3c331a..5c41d78 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.eo
+++ b/src/lib/ecore_con/efl_net_dialer_http.eo
@@ -334,6 +334,29 @@ class Efl.Net.Dialer.Http (Efl.Loop_User, Efl.Net.Dialer, 
Efl.Io.Sizer) {
                 path: string; [[Path to cookie jar]]
             }
         }
+
+        date_parse @class {
+            [[Parse the given string as time in seconds since 1/1/1970.
+
+              This method is useful to parse header values such as
+              "Last-Modified".
+            ]]
+            params {
+                str: string; [[String in HTTP text format: Tue, 15 Nov 1994 
12:45:26 GMT]]
+            }
+            return: long; [[Seconds since 1/1/1970]]
+        }
+
+        date_serialize @class {
+            [[Serialize the given GMT time in seconds since 1/1/1970.
+
+              The timezone must be GMT (ie: gmtime()).
+            ]]
+            params {
+                epochtime: long; [[UNIX Epoch time - seconds since 1/1/1970]]
+            }
+            return: free(own(ptr(char)), free) @warn_unused; [[Newly allocated 
null-terminated string on success or NULL on errors]]
+        }
     }
 
     events {

-- 


Reply via email to