barbieri pushed a commit to branch master.

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

commit f0f9c5d24a0a261367371fd420bc3a3e04b5285f
Author: Gustavo Sverzut Barbieri <barbi...@profusion.mobi>
Date:   Tue Sep 20 15:00:17 2016 -0300

    libproxy: dlopen() and make it runtime optional.
---
 configure.ac                            |  13 ----
 src/lib/ecore_con/ecore_con.c           | 132 ++++++++++++++++++++++----------
 src/lib/ecore_con/ecore_con_private.h   |  10 ++-
 src/lib/ecore_con/efl_net_dialer_http.c |  16 +---
 4 files changed, 101 insertions(+), 70 deletions(-)

diff --git a/configure.ac b/configure.ac
index a403484..d0b9962 100644
--- a/configure.ac
+++ b/configure.ac
@@ -224,7 +224,6 @@ case "$host_os" in
    ;;
    freebsd*)
       have_freebsd="yes"
-      want_libproxy="yes"
       ELM_UNIX_DEF="#define"
    ;;
    darwin*)
@@ -235,7 +234,6 @@ case "$host_os" in
       have_linux="yes"
       have_systemd_pkg="auto"
       want_systemd="yes"
-      want_libproxy="yes"
       ELM_UNIX_DEF="#define"
    ;;
    *)
@@ -3034,16 +3032,6 @@ 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"
 
@@ -3080,7 +3068,6 @@ 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 d79c77e..cc17fe8 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -191,9 +191,15 @@ 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
+typedef struct pxProxyFactory_  pxProxyFactory;
+typedef struct _Ecore_Con_Libproxy {
+   pxProxyFactory *factory;
+   char **(*px_proxy_factory_get_proxies)(pxProxyFactory *factory, const char 
*url);
+   void *(*px_proxy_factory_new)(void);
+   void (*px_proxy_factory_free)(pxProxyFactory *);
+   Eina_Module *mod;
+} Ecore_Con_Libproxy;
+static Ecore_Con_Libproxy _ecore_con_libproxy;
 
 EAPI int
 ecore_con_init(void)
@@ -279,13 +285,16 @@ ecore_con_shutdown(void)
    if (--_ecore_con_init_count != 0)
      return _ecore_con_init_count;
 
-#ifdef HAVE_LIBPROXY
-   if (_ecore_con_libproxy_factory)
+   if (_ecore_con_libproxy.factory)
      {
-        px_proxy_factory_free(_ecore_con_libproxy_factory);
-        _ecore_con_libproxy_factory = NULL;
+        _ecore_con_libproxy.px_proxy_factory_free(_ecore_con_libproxy.factory);
+        _ecore_con_libproxy.factory = NULL;
+     }
+   if (_ecore_con_libproxy.mod)
+     {
+        eina_module_free(_ecore_con_libproxy.mod);
+        _ecore_con_libproxy.mod = NULL;
      }
-#endif
 
    eina_log_timing(_ecore_con_log_dom,
                    EINA_LOG_STATE_START,
@@ -4444,32 +4453,15 @@ 
_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)
@@ -4489,8 +4481,7 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
 
    proxy = d->proxy;
 
-#ifdef HAVE_LIBPROXY
-   if ((!proxy) && (_ecore_con_libproxy_factory))
+   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
@@ -4499,11 +4490,11 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
         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);
+        proxies = ecore_con_libproxy_proxies_get(url);
         free(url);
      }
 
-   EINA_THREAD_CLEANUP_PUSH(_cleanup_proxies, proxies);
+   EINA_THREAD_CLEANUP_PUSH((Eina_Free_Cb)ecore_con_libproxy_proxies_free, 
proxies);
  next_proxy:
    if ((!proxy) && (proxies) && (proxies_idx >= 0))
      {
@@ -4529,7 +4520,6 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread 
*thread EINA_UNUSED)
              proxies_idx++;
           }
      }
-#endif
 
    if (!proxy)
      {
@@ -4581,14 +4571,12 @@ _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);
@@ -4597,23 +4585,19 @@ _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);
 }
 
@@ -4714,10 +4698,6 @@ 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,
@@ -4734,3 +4714,75 @@ efl_net_ip_connect_async_new(const char *address, const 
char *proxy, const char
    free(d);
    return NULL;
 }
+
+Eina_Bool
+ecore_con_libproxy_init(void)
+{
+   if (!_ecore_con_libproxy.mod)
+     {
+#define LOAD(x)                                                         \
+          if (!_ecore_con_libproxy.mod) {                               \
+             _ecore_con_libproxy.mod = eina_module_new(x);              \
+             if (_ecore_con_libproxy.mod) {                             \
+                if (!eina_module_load(_ecore_con_libproxy.mod)) {       \
+                   eina_module_free(_ecore_con_libproxy.mod);           \
+                   _ecore_con_libproxy.mod = NULL;                      \
+                }                                                       \
+             }                                                          \
+          }
+#if defined(_WIN32) || defined(__CYGWIN__)
+        LOAD("libproxy-1.dll");
+        LOAD("libproxy.dll");
+#elif defined(__APPLE__) && defined(__MACH__)
+        LOAD("libproxy.1.dylib");
+        LOAD("libproxy.dylib");
+#else
+        LOAD("libproxy.so.1");
+        LOAD("libproxy.so");
+#endif
+#undef LOAD
+        if (!_ecore_con_libproxy.mod)
+          {
+             DBG("Couldn't find libproxy in your system. Continue without it");
+             return EINA_FALSE;
+          }
+
+#define SYM(x)                                                          \
+        if ((_ecore_con_libproxy.x = 
eina_module_symbol_get(_ecore_con_libproxy.mod, #x)) == NULL) { \
+           ERR("libproxy (%s) missing symbol %s", 
eina_module_file_get(_ecore_con_libproxy.mod), #x); \
+           eina_module_free(_ecore_con_libproxy.mod);                   \
+           _ecore_con_libproxy.mod = NULL;                              \
+           return EINA_FALSE;                                           \
+        }
+
+        SYM(px_proxy_factory_new);
+        SYM(px_proxy_factory_free);
+        SYM(px_proxy_factory_get_proxies);
+#undef SYM
+        DBG("using libproxy=%s", 
eina_module_file_get(_ecore_con_libproxy.mod));
+     }
+
+   if (!_ecore_con_libproxy.factory)
+     _ecore_con_libproxy.factory = _ecore_con_libproxy.px_proxy_factory_new();
+
+   return !!_ecore_con_libproxy.factory;
+}
+
+char **
+ecore_con_libproxy_proxies_get(const char *url)
+{
+   
EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_con_libproxy.px_proxy_factory_get_proxies,
 NULL);
+   return 
_ecore_con_libproxy.px_proxy_factory_get_proxies(_ecore_con_libproxy.factory, 
url);
+}
+
+void
+ecore_con_libproxy_proxies_free(char **proxies)
+{
+   char **itr;
+
+   if (!proxies) return;
+
+   for (itr = proxies; *itr != NULL; itr++)
+     free(*itr);
+   free(proxies);
+}
diff --git a/src/lib/ecore_con/ecore_con_private.h 
b/src/lib/ecore_con/ecore_con_private.h
index 82e2d44..f85433b 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -254,10 +254,12 @@ extern int sd_fd_index;
 extern int sd_fd_max;
 #endif
 
-#ifdef HAVE_LIBPROXY
-# include <proxy.h>
-extern pxProxyFactory *_ecore_con_libproxy_factory;
-#endif
+/* init must be called from main thread */
+Eina_Bool ecore_con_libproxy_init(void);
+void ecore_con_libproxy_proxies_free(char **proxies);
+/* BLOCKING! should be called from a worker thread */
+char **ecore_con_libproxy_proxies_get(const char *url);
+
 
 extern Ecore_Con_Socks *_ecore_con_proxy_once;
 extern Ecore_Con_Socks *_ecore_con_proxy_global;
diff --git a/src/lib/ecore_con/efl_net_dialer_http.c 
b/src/lib/ecore_con/efl_net_dialer_http.c
index 1b5b20b..9e16d8a 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.c
+++ b/src/lib/ecore_con/efl_net_dialer_http.c
@@ -181,9 +181,7 @@ typedef struct
    Eina_Stringshare *address_remote;
    Eina_Stringshare *method;
    Eina_Stringshare *user_agent;
-#ifdef HAVE_LIBPROXY
    Ecore_Thread *libproxy_thread;
-#endif
    struct {
       struct curl_slist *headers;
       int64_t content_length;
@@ -1169,13 +1167,12 @@ _efl_net_dialer_http_efl_object_constructor(Eo *o, 
Efl_Net_Dialer_Http_Data *pd)
 EOLIAN static void
 _efl_net_dialer_http_efl_object_destructor(Eo *o, Efl_Net_Dialer_Http_Data *pd)
 {
-#ifdef HAVE_LIBPROXY
    if (pd->libproxy_thread)
      {
         ecore_thread_cancel(pd->libproxy_thread);
         pd->libproxy_thread = NULL;
      }
-#endif
+
    if (pd->in_curl_callback)
      {
         DBG("deleting HTTP dialer=%p from CURL callback.", o);
@@ -1263,7 +1260,6 @@ _efl_net_dialer_http_curl_start(Eo *o, 
Efl_Net_Dialer_Http_Data *pd)
    DBG("started curl request easy=%p, cm=%p", pd->easy, pd->cm);
 }
 
-#ifdef HAVE_LIBPROXY
 typedef struct _Efl_Net_Dialer_Http_Libproxy_Context {
    Eo *o;
    char *url;
@@ -1274,7 +1270,7 @@ static void
 _efl_net_dialer_http_libproxy_run(void *data, Ecore_Thread *thread EINA_UNUSED)
 {
    Efl_Net_Dialer_Http_Libproxy_Context *ctx = data;
-   char **proxies = px_proxy_factory_get_proxies(_ecore_con_libproxy_factory, 
ctx->url);
+   char **proxies = ecore_con_libproxy_proxies_get(ctx->url);
    char **itr;
 
    if (!proxies) return;
@@ -1332,7 +1328,6 @@ _efl_net_dialer_http_libproxy_cancel(void *data, 
Ecore_Thread *thread EINA_UNUSE
    Efl_Net_Dialer_Http_Libproxy_Context *ctx = data;
    _efl_net_dialer_http_libproxy_context_free(ctx);
 }
-#endif
 
 EOLIAN static Eina_Error
 _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, 
const char *address)
@@ -1357,14 +1352,10 @@ _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, 
Efl_Net_Dialer_Http_Data *pd, co
         return EINVAL;
      }
 
-#ifdef HAVE_LIBPROXY
-   if (!pd->proxy)
+   if ((!pd->proxy) && (ecore_con_libproxy_init()))
      {
         Efl_Net_Dialer_Http_Libproxy_Context *ctx;
 
-        if (!_ecore_con_libproxy_factory)
-          _ecore_con_libproxy_factory = px_proxy_factory_new();
-
         if (pd->libproxy_thread)
           ecore_thread_cancel(pd->libproxy_thread);
 
@@ -1394,7 +1385,6 @@ _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, 
Efl_Net_Dialer_Http_Data *pd, co
         free(ctx);
         return ENOMEM;
      }
-#endif
 
    _efl_net_dialer_http_curl_start(o, pd);
 

-- 


Reply via email to