From: Bluezery <ohpowel@gmail.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 21 Dec 2011 06:18:25 +0000 (06:18 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 21 Dec 2011 06:18:25 +0000 (06:18 +0000)
Subject: Re: [E-devel] [Patch][ecore_con_url] Add proxy & timeout set
API

There existed two problems when using ecore_con_url. We cannot set
proxy and set timeout.
So, I added two APIs for solving these problems.
Proxy can be set by setting libcurl option.
Timeout also can be set but It need to add handler for Linux alarm
signal. (Please refer:
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTIMEOUT)
So I implemented it by using ecore timer.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@66414 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
src/lib/ecore_con/Ecore_Con.h
src/lib/ecore_con/ecore_con_private.h
src/lib/ecore_con/ecore_con_url.c
src/lib/ecore_file/ecore_file_download.c

index a8a0a1a..4d77005 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Add XIM attribute support to Ecore_IMF
 
+2011-12-21 Tae-Hwan Kim (Bluezery)
+
+       * Add proxy set and timeout set functions in ecore_con.
diff --git a/NEWS b/NEWS
index 1da17af..ae24d72 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ Additions:
      - ecore_con_ssl_server_verify_name_set/get
      - ecore_con_ssl_server_cafile_add() now accepts directories
      - ECORE_CON_REMOTE_CORK
+     - ecore_con_url_proxy_set()
+     - ecore_con_url_timeout_set()
     * ecore_x:
      - ecore_x_randr_output_backlight_available()
 
index d6df0ce..cd39f08 100644 (file)
@@ -1845,6 +1845,39 @@ EAPI int               ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con,
                                                 const char *ca_path);
 
 /**
+ * Set HTTP proxy to use.
+ *
+ * The parameter should be a char * to a zero terminated string holding
+ * the host name or dotted IP address. To specify port number in this string,
+ * append :[port] to the end of the host name.
+ * The proxy string may be prefixed with [protocol]:// since any such prefix
+ * will be ignored.
+ * The proxy's port number may optionally be specified with the separate option.
+ * If not specified, libcurl will default to using port 1080 for proxies.
+ *
+ * @param url_con Connection object that will use the proxy.
+ * @param proxy Porxy string or @c NULL to disable
+ *
+ * @return #EINA_TRUE on success, #EINA_FALSE on error.
+ * @since 1.2
+ */
+EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy);
+
+/**
+ * Set timeout in seconds.
+ *
+ * the maximum time in seconds that you allow the ecore con url transfer
+ * operation to take. Normally, name lookups can take a considerable time
+ * and limiting operations to less than a few minutes risk aborting perfectly
+ * normal operations.
+ *
+ * @param url_con Connection object that will use the timeout.
+ * @param timeout time in seconds.
+ * @since 1.2
+ */
+EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout);
+
+/**
  * @}
  */
 
index 2aef902..098c520 100644 (file)
@@ -204,6 +204,8 @@ struct _Ecore_Con_Url
    Eina_List *response_headers;
    const char *url;
 
+   Ecore_Timer *timer;
+
    Ecore_Con_Url_Time time_condition;
    double timestamp;
    void *data;
index cf6c216..ea6dd4c 100644 (file)
@@ -57,6 +57,7 @@ static void      _ecore_con_event_url_free(void *data __UNUSED__,
                                            void      *ev);
 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_timeout_cb(void *data);
 
 static Eina_List *_url_con_list = NULL;
 static Eina_List *_fd_hd_list = NULL;
@@ -294,12 +295,13 @@ ecore_con_url_free(Ecore_Con_Url *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);
      }
+   if (url_con->timer) ecore_timer_del(url_con->timer);
 
-   _url_con_list = eina_list_remove(_url_con_list, url_con);
    curl_slist_free_all(url_con->headers);
    EINA_LIST_FREE(url_con->additional_headers, s)
      free(s);
@@ -1067,12 +1069,93 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
    return res;
 }
 
+EAPI Eina_Bool
+ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy)
+{
+#ifdef HAVE_CURL
+   int res = -1;
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+     {
+        ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_set");
+        return EINA_FALSE;
+     }
+
+   if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
+   if (!url_con->url) return EINA_FALSE;
+
+   if (proxy == NULL) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, "");
+   else               res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, proxy);
+
+   if (res != CURLE_OK)
+     {
+        ERR("curl_easy_setopt() failed");
+        return EINA_FALSE;
+     }
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+   (void)url_con;
+   (void)proxy;
+#endif
+   return res;
+}
+
+EAPI void
+ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout)
+{
+#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_timeout_set");
+        return;
+     }
+
+   if (eina_list_data_find(_url_con_list, url_con)) return;
+   if (!url_con->url || timeout < 0) return;
+   if (url_con->timer) ecore_timer_del(url_con->timer);
+   url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con);
+#else
+   return;
+   (void)url_con;
+   (void)timeout;
+#endif
+}
 
 /**
  * @}
  */
 
 #ifdef HAVE_CURL
+static Eina_Bool
+_ecore_con_url_timeout_cb(void *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->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);
+   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_slist_free_all(url_con->headers);
+   url_con->headers = NULL;
+
+   url_con->timer = NULL;
+
+   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);
+     }
+   return ECORE_CALLBACK_CANCEL;
+}
+
 static size_t
 _ecore_con_url_data_cb(void  *buffer,
                        size_t size,
index 38855ad..c5e56bd 100644 (file)
@@ -15,6 +15,7 @@
 #ifdef BUILD_ECORE_CON
 
 #define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8
+#define ECORE_FILE_DOWNLOAD_TIMEOUT 30
 
 struct _Ecore_File_Download_Job
 {
@@ -361,6 +362,7 @@ _ecore_file_download_curl(const char *url, const char *dst,
      }
 
    if (headers) eina_hash_foreach(headers, _ecore_file_download_headers_foreach_cb, job);
+   ecore_con_url_timeout_set(job->url_con, ECORE_FILE_DOWNLOAD_TIMEOUT);
    ecore_con_url_fd_set(job->url_con, fileno(job->file));
    ecore_con_url_data_set(job->url_con, data);