barbieri pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0d478c301f49fccfd94a107c060696f79490c30d

commit 0d478c301f49fccfd94a107c060696f79490c30d
Author: Gustavo Sverzut Barbieri <barbi...@profusion.mobi>
Date:   Mon Sep 19 03:19:16 2016 -0300

    efl_net_dialer_tcp: use libproxy settings.
    
    libproxy allows various means to configure a proxy, will load from
    gnome and kde configuration settings, envvars, macos and even windows
    registry.
    
    curl still doesn't use it, but we can make that later.
---
 configure.ac                          |  13 ++++
 src/lib/ecore_con/ecore_con.c         | 110 +++++++++++++++++++++++++++++++++-
 src/lib/ecore_con/ecore_con_private.h |   5 ++
 3 files changed, 127 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index d0b9962..a403484 100644
--- a/configure.ac
+++ b/configure.ac
@@ -224,6 +224,7 @@ case "$host_os" in
    ;;
    freebsd*)
       have_freebsd="yes"
+      want_libproxy="yes"
       ELM_UNIX_DEF="#define"
    ;;
    darwin*)
@@ -234,6 +235,7 @@ case "$host_os" in
       have_linux="yes"
       have_systemd_pkg="auto"
       want_systemd="yes"
+      want_libproxy="yes"
       ELM_UNIX_DEF="#define"
    ;;
    *)
@@ -3032,6 +3034,16 @@ EFL_LIB_START([Ecore_Con])
 
 ### Default values
 
+AC_ARG_ENABLE([libproxy],
+   [AS_HELP_STRING([--enable-libproxy],[Enable libproxy support. 
@<:@default=enabled@:>@])],
+   [
+    if test "x${enableval}" = "xyes" ; then
+       want_libproxy="yes"
+    else
+       want_libproxy="no"
+    fi
+   ])
+
 want_ecore_con_local_sockets="yes"
 want_ecore_con_abstract_sockets="yes"
 
@@ -3068,6 +3080,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_CON], [emile])
 EFL_ADD_LIBS([ECORE_CON], [-lm])
 
 EFL_OPTIONAL_DEPEND_PKG([ECORE_CON], [${want_systemd}], [SYSTEMD], 
[libsystemd])
+EFL_OPTIONAL_DEPEND_PKG([ECORE_CON], [${want_libproxy}], [LIBPROXY], 
[libproxy-1.0])
 
 EFL_ADD_FEATURE([ECORE_CON], [local-sockets], 
[${want_ecore_con_local_sockets}])
 EFL_ADD_FEATURE([ECORE_CON], [abstract-sockets], 
[${want_ecore_con_abstract_sockets}])
diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c
index 7d8c379..d79c77e 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -191,6 +191,10 @@ int _ecore_con_log_dom = -1;
 Ecore_Con_Socks *_ecore_con_proxy_once = NULL;
 Ecore_Con_Socks *_ecore_con_proxy_global = NULL;
 
+#ifdef HAVE_LIBPROXY
+pxProxyFactory *_ecore_con_libproxy_factory = NULL;
+#endif
+
 EAPI int
 ecore_con_init(void)
 {
@@ -275,6 +279,14 @@ ecore_con_shutdown(void)
    if (--_ecore_con_init_count != 0)
      return _ecore_con_init_count;
 
+#ifdef HAVE_LIBPROXY
+   if (_ecore_con_libproxy_factory)
+     {
+        px_proxy_factory_free(_ecore_con_libproxy_factory);
+        _ecore_con_libproxy_factory = NULL;
+     }
+#endif
+
    eina_log_timing(_ecore_con_log_dom,
                    EINA_LOG_STATE_START,
                    EINA_LOG_STATE_SHUTDOWN);
@@ -4432,12 +4444,32 @@ 
_efl_net_ip_connect_async_run_socks5h(Efl_Net_Ip_Connect_Async_Data *d, const ch
    EINA_THREAD_CLEANUP_POP(EINA_TRUE); /* free(str) */
 }
 
+#ifdef HAVE_LIBPROXY
+static void
+_cleanup_proxies(void *data)
+{
+   char **proxies = data;
+   char **itr;
+
+   if (!proxies) return;
+
+   for (itr = proxies; *itr != NULL; itr++)
+     free(*itr);
+   free(proxies);
+}
+#endif
+
 static void
 _efl_net_ip_connect_async_run(void *data, Ecore_Thread *thread EINA_UNUSED)
 {
    Efl_Net_Ip_Connect_Async_Data *d = data;
    const char *host, *port, *proxy;
    char *addrcopy;
+#ifdef HAVE_LIBPROXY
+   char **proxies = NULL;
+   int proxies_idx = 0;
+   Eina_Bool is_libproxy = EINA_FALSE;
+#endif
 
    addrcopy = strdup(d->address);
    if (!addrcopy)
@@ -4453,8 +4485,52 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
         return;
      }
    if (!port) port = "0";
+   EINA_THREAD_CLEANUP_PUSH(free, addrcopy);
 
    proxy = d->proxy;
+
+#ifdef HAVE_LIBPROXY
+   if ((!proxy) && (_ecore_con_libproxy_factory))
+     {
+        /* libproxy is thread-safe but not cancellable.  the provided
+         * parameter must be a URL with schema, otherwise it won't
+         * return anything.
+         */
+        char *url;
+
+        asprintf(&url, "%s://%s:%s", d->protocol == IPPROTO_UDP ? "udp" : 
"tcp", host, port);
+        proxies = px_proxy_factory_get_proxies(_ecore_con_libproxy_factory, 
url);
+        free(url);
+     }
+
+   EINA_THREAD_CLEANUP_PUSH(_cleanup_proxies, proxies);
+ next_proxy:
+   if ((!proxy) && (proxies) && (proxies_idx >= 0))
+     {
+        proxy = proxies[proxies_idx];
+        if (!proxy)
+          {
+             is_libproxy = EINA_FALSE;
+             proxies_idx = -1;
+          }
+        else
+          {
+             if (strcmp(proxy, "direct://") == 0)
+               {
+                  /* give a chance to try envvars */
+                  proxy = NULL;
+                  is_libproxy = EINA_FALSE;
+               }
+             else
+               {
+                  DBG("libproxy said %s for host='%s' port='%s'", proxy, host, 
port);
+                  is_libproxy = EINA_TRUE;
+               }
+             proxies_idx++;
+          }
+     }
+#endif
+
    if (!proxy)
      {
         proxy = d->proxy_env;
@@ -4464,10 +4540,11 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
           {
              if (_efl_net_ip_no_proxy(host, d->no_proxy_strv))
                proxy = "";
+             else
+               DBG("using proxy %s from envvar", proxy);
           }
      }
 
-   EINA_THREAD_CLEANUP_PUSH(free, addrcopy);
    /* allows ecore_thread_cancel() to cancel at some points, see
     * man:pthreads(7).
     */
@@ -4483,6 +4560,12 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
      _efl_net_ip_connect_async_run_socks4a(d, host, port, proxy + 
strlen("socks4a://"));
    else if (eina_str_has_prefix(proxy, "socks5h://"))
      _efl_net_ip_connect_async_run_socks5h(d, host, port, proxy + 
strlen("socks5h://"));
+   else if (eina_str_has_prefix(proxy, "socks://"))
+     {
+        _efl_net_ip_connect_async_run_socks5(d, host, port, proxy + 
strlen("socks://"));
+        if (d->error)
+          _efl_net_ip_connect_async_run_socks4(d, host, port, proxy + 
strlen("socks://"));
+     }
    else if (!strstr(proxy, "://"))
      {
         _efl_net_ip_connect_async_run_socks5(d, host, port, proxy);
@@ -4498,6 +4581,14 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
           }
         else
           {
+#ifdef HAVE_LIBPROXY
+             if (is_libproxy)
+               {
+                  DBG("libproxy said %s but it's not supported, try next 
proxy", proxy);
+                  proxy = NULL;
+                  goto next_proxy;
+               }
+#endif
              /* maybe bogus envvar, ignore it */
              WRN("proxy protocol not supported '%s', connect directly", proxy);
              _efl_net_ip_connect_async_run_direct(d, host, port);
@@ -4506,11 +4597,23 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
 
    if ((d->error) && (!d->proxy) && (proxy[0] != '\0'))
      {
+#ifdef HAVE_LIBPROXY
+        if (is_libproxy)
+          {
+             DBG("libproxy said %s but it failed, try next proxy", proxy);
+             proxy = NULL;
+             goto next_proxy;
+          }
+#endif
+
         WRN("error using proxy '%s' from environment, try direct connect", 
proxy);
         _efl_net_ip_connect_async_run_direct(d, host, port);
      }
 
    eina_thread_cancellable_set(EINA_FALSE, NULL);
+#ifdef HAVE_LIBPROXY
+   EINA_THREAD_CLEANUP_POP(EINA_TRUE);
+#endif
    EINA_THREAD_CLEANUP_POP(EINA_TRUE);
 }
 
@@ -4611,6 +4714,11 @@ efl_net_ip_connect_async_new(const char *address, const 
char *proxy, const char
    d->sockfd = -1;
    d->error = 0;
 
+#ifdef HAVE_LIBPROXY
+   if (!_ecore_con_libproxy_factory)
+     _ecore_con_libproxy_factory = px_proxy_factory_new();
+#endif
+
    return ecore_thread_run(_efl_net_ip_connect_async_run,
                            _efl_net_ip_connect_async_end,
                            _efl_net_ip_connect_async_cancel,
diff --git a/src/lib/ecore_con/ecore_con_private.h 
b/src/lib/ecore_con/ecore_con_private.h
index 6437e83..82e2d44 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -254,6 +254,11 @@ extern int sd_fd_index;
 extern int sd_fd_max;
 #endif
 
+#ifdef HAVE_LIBPROXY
+# include <proxy.h>
+extern pxProxyFactory *_ecore_con_libproxy_factory;
+#endif
+
 extern Ecore_Con_Socks *_ecore_con_proxy_once;
 extern Ecore_Con_Socks *_ecore_con_proxy_global;
 void ecore_con_socks_init(void);

-- 


Reply via email to