summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/Makefile_Ecore_Con.am24
-rw-r--r--src/bin/ecore_con/efl_net_proxy_helper.c264
-rw-r--r--src/lib/ecore_con/ecore_con.c91
-rw-r--r--src/lib/ecore_con/ecore_con_private.h1
-rw-r--r--src/lib/ecore_con/ecore_con_proxy_helper.c427
-rw-r--r--src/lib/ecore_con/efl_net_dialer_http.c2
7 files changed, 728 insertions, 82 deletions
diff --git a/.gitignore b/.gitignore
index 0dbb552..b00829a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,3 +76,4 @@ Session.vim
76/elm_intro.h 76/elm_intro.h
77/src/modules/evas/engines/gl_common/shader_3d/evas_3d_shaders.x 77/src/modules/evas/engines/gl_common/shader_3d/evas_3d_shaders.x
78/src/scripts/eo/eo_debug 78/src/scripts/eo/eo_debug
79/src/bin/ecore_con/efl_net_proxy_helper
diff --git a/src/Makefile_Ecore_Con.am b/src/Makefile_Ecore_Con.am
index 3c62337..093c26a 100644
--- a/src/Makefile_Ecore_Con.am
+++ b/src/Makefile_Ecore_Con.am
@@ -80,6 +80,7 @@ nodist_installed_ecoreconmainheaders_DATA = \
80lib_ecore_con_libecore_con_la_SOURCES = \ 80lib_ecore_con_libecore_con_la_SOURCES = \
81lib/ecore_con/ecore_con_alloc.c \ 81lib/ecore_con/ecore_con_alloc.c \
82lib/ecore_con/ecore_con.c \ 82lib/ecore_con/ecore_con.c \
83lib/ecore_con/ecore_con_proxy_helper.c \
83lib/ecore_con/ecore_con_legacy.c \ 84lib/ecore_con/ecore_con_legacy.c \
84lib/ecore_con/ecore_con_eet.c \ 85lib/ecore_con/ecore_con_eet.c \
85lib/ecore_con/ecore_con_socks.c \ 86lib/ecore_con/ecore_con_socks.c \
@@ -152,7 +153,12 @@ lib/ecore_con/efl_net_dialer_unix.c \
152lib/ecore_con/efl_net_server_unix.c 153lib/ecore_con/efl_net_server_unix.c
153endif 154endif
154 155
155lib_ecore_con_libecore_con_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_CON_CFLAGS@ 156lib_ecore_con_libecore_con_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
157-DPACKAGE_BIN_DIR=\"$(bindir)\" \
158-DPACKAGE_LIB_DIR=\"$(libdir)\" \
159-DPACKAGE_DATA_DIR=\"$(datadir)/ecore\" \
160-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
161@ECORE_CON_CFLAGS@
156lib_ecore_con_libecore_con_la_LIBADD = @ECORE_CON_LIBS@ @EVIL_LIBS@ 162lib_ecore_con_libecore_con_la_LIBADD = @ECORE_CON_LIBS@ @EVIL_LIBS@
157lib_ecore_con_libecore_con_la_DEPENDENCIES = @ECORE_CON_INTERNAL_LIBS@ 163lib_ecore_con_libecore_con_la_DEPENDENCIES = @ECORE_CON_INTERNAL_LIBS@
158lib_ecore_con_libecore_con_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ 164lib_ecore_con_libecore_con_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
@@ -169,6 +175,22 @@ static_libs/http-parser/test.c \
169static_libs/http-parser/contrib/parsertrace.c \ 175static_libs/http-parser/contrib/parsertrace.c \
170static_libs/http-parser/contrib/url_parser.c 176static_libs/http-parser/contrib/url_parser.c
171 177
178### Binary
179proxyhelperdir = \
180$(libdir)/ecore_con/utils/$(MODULE_ARCH)
181proxyhelper_PROGRAMS = bin/ecore_con/efl_net_proxy_helper
182
183bin_ecore_con_efl_net_proxy_helper_SOURCES = \
184bin/ecore_con/efl_net_proxy_helper.c
185
186bin_ecore_con_efl_net_proxy_helper_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
187-DPACKAGE_BIN_DIR=\"$(bindir)\" \
188-DPACKAGE_LIB_DIR=\"$(libdir)\" \
189-DPACKAGE_DATA_DIR=\"$(datadir)/ecore\" \
190@EINA_CFLAGS@
191bin_ecore_con_efl_net_proxy_helper_LDADD = @USE_EINA_LIBS@
192bin_ecore_con_efl_net_proxy_helper_DEPEDNENCIES = @USE_EINA_INTERNAL_LIBS@
193
172### Unit tests 194### Unit tests
173 195
174if EFL_ENABLE_TESTS 196if EFL_ENABLE_TESTS
diff --git a/src/bin/ecore_con/efl_net_proxy_helper.c b/src/bin/ecore_con/efl_net_proxy_helper.c
new file mode 100644
index 0000000..69c371a
--- /dev/null
+++ b/src/bin/ecore_con/efl_net_proxy_helper.c
@@ -0,0 +1,264 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <errno.h>
10#include <unistd.h>
11#include <fcntl.h>
12
13#ifdef HAVE_EVIL
14# include <Evil.h>
15#endif
16
17#include "Eina.h"
18
19#ifdef ERR
20# undef ERR
21#endif
22#define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
23
24#ifdef DBG
25# undef DBG
26#endif
27#define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
28
29#ifdef INF
30# undef INF
31#endif
32#define INF(...) EINA_LOG_DOM_INFO(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
33
34#ifdef WRN
35# undef WRN
36#endif
37#define WRN(...) EINA_LOG_DOM_WARN(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
38
39#ifdef CRI
40# undef CRI
41#endif
42#define CRI(...) EINA_LOG_DOM_CRIT(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
43
44typedef struct pxProxyFactory_ pxProxyFactory;
45typedef struct _Libproxy
46{
47 pxProxyFactory *factory;
48 char **(*px_proxy_factory_get_proxies) (pxProxyFactory *factory, const char *url);
49 void *(*px_proxy_factory_new) (void);
50 void (*px_proxy_factory_free) (pxProxyFactory *);
51 Eina_Module *mod;
52} Libproxy;
53static Libproxy _libproxy = { 0 };
54
55static Eina_Spinlock pending_lock;
56static int pending = 0;
57static int opcount = 0;
58static Eina_List *join_list = NULL;
59
60static Eina_Bool
61init(void)
62{
63 if (!_libproxy.mod)
64 {
65#define LOAD(x) \
66 if (!_libproxy.mod) { \
67 _libproxy.mod = eina_module_new(x); \
68 if (_libproxy.mod) { \
69 if (!eina_module_load(_libproxy.mod)) { \
70 eina_module_free(_libproxy.mod); \
71 _libproxy.mod = NULL; \
72 } \
73 } \
74 }
75#if defined(_WIN32) || defined(__CYGWIN__)
76 LOAD("libproxy-1.dll");
77 LOAD("libproxy.dll");
78#elif defined(__APPLE__) && defined(__MACH__)
79 LOAD("libproxy.1.dylib");
80 LOAD("libproxy.dylib");
81#else
82 LOAD("libproxy.so.1");
83 LOAD("libproxy.so");
84#endif
85#undef LOAD
86 if (!_libproxy.mod)
87 {
88 DBG("Couldn't find libproxy in your system. Continue without it");
89 return EINA_FALSE;
90 }
91
92#define SYM(x) \
93 if ((_libproxy.x = eina_module_symbol_get(_libproxy.mod, #x)) == NULL) { \
94 ERR("libproxy (%s) missing symbol %s", \
95 eina_module_file_get(_libproxy.mod), #x); \
96 eina_module_free(_libproxy.mod); \
97 _libproxy.mod = NULL; \
98 return EINA_FALSE; \
99 }
100
101 SYM(px_proxy_factory_new);
102 SYM(px_proxy_factory_free);
103 SYM(px_proxy_factory_get_proxies);
104#undef SYM
105 DBG("using libproxy=%s", eina_module_file_get(_libproxy.mod));
106 }
107
108 if (!_libproxy.factory)
109 _libproxy.factory = _libproxy.px_proxy_factory_new();
110
111 return !!_libproxy.factory;
112}
113
114static void
115shutdown(void)
116{
117 if (_libproxy.factory)
118 {
119 _libproxy.px_proxy_factory_free(_libproxy.factory);
120 _libproxy.factory = NULL;
121 }
122 if (_libproxy.mod)
123 {
124 eina_module_free(_libproxy.mod);
125 _libproxy.mod = NULL;
126 }
127}
128
129static void *
130proxy_lookup(void *data, Eina_Thread t)
131{
132 char *cmd = data;
133 char **proxies, **itr;
134 const char *p, *url;
135 int id = atoi(cmd + 2);
136 int pending_local, opcount_prev;
137
138 if (id > 0)
139 {
140 for (p = cmd + 2; *p && (*p != ' '); p++);
141 if (*p == ' ')
142 {
143 url = p + 1;
144 proxies = _libproxy.px_proxy_factory_get_proxies
145 (_libproxy.factory, url);
146 if (proxies)
147 {
148 for (itr = proxies; *itr != NULL; itr++)
149 {
150 fprintf(stdout, "P %i P %s\n", id, *itr);
151 free(*itr);
152 }
153 free(proxies);
154 }
155 fprintf(stdout, "P %i E\n", id);
156 fflush(stdout);
157 }
158 }
159 free(cmd);
160
161 eina_spinlock_take(&pending_lock);
162 {
163 pending--;
164 pending_local = pending;
165 opcount_prev = opcount;
166 }
167 eina_spinlock_release(&pending_lock);
168 // if there are no more pending threads doing work - sleep for the
169 // timeout then check if we still are and if so - exit;
170 if (pending_local == 0) sleep(10);
171 eina_spinlock_take(&pending_lock);
172 {
173 Eina_Thread *tt;
174
175 if ((pending == 0) & (opcount == opcount_prev)) exit(0);
176 tt = calloc(1, sizeof(Eina_Thread));
177 if (tt)
178 {
179 *tt = t;
180 join_list = eina_list_append(join_list, tt);
181 }
182 }
183 eina_spinlock_release(&pending_lock);
184 return NULL;
185}
186
187static void
188handle(const char *cmd)
189{
190 // "P 1234 URL" -> Get Proxy, id=1234, url=URL
191 if ((cmd[0] == 'P') && (cmd[1] == ' '))
192 {
193 char *dup = strdup(cmd);
194
195 if (dup)
196 {
197 Eina_Thread t;
198
199 eina_spinlock_take(&pending_lock);
200 {
201 pending++;
202 opcount++;
203 }
204 eina_spinlock_release(&pending_lock);
205 if (!eina_thread_create(&t, EINA_THREAD_BACKGROUND, -1,
206 proxy_lookup, dup))
207 {
208 abort();
209 }
210 }
211 return;
212 }
213}
214
215static void
216clean_threads(void)
217{
218 eina_spinlock_take(&pending_lock);
219 {
220 Eina_Thread *t;
221
222 EINA_LIST_FREE(join_list, t)
223 {
224 eina_thread_join(*t);
225 free(t);
226 }
227 }
228 eina_spinlock_release(&pending_lock);
229}
230
231int
232main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
233{
234 char inbuf[8192];
235 eina_init();
236 if (init())
237 {
238 eina_spinlock_new(&pending_lock);
239 // 1 command per stdin line
240 while (fgets(inbuf, sizeof(inbuf) - 1, stdin))
241 {
242 // strip off newline and ensure the string is 0 terminated
243 int len = strlen(inbuf);
244 if (len > 0)
245 {
246 if (inbuf[len -1 ] == '\n') inbuf[len - 1] = 0;
247 else inbuf[len] = 0;
248 handle(inbuf);
249 }
250 clean_threads();
251 }
252 eina_spinlock_free(&pending_lock);
253 shutdown();
254 }
255 else
256 {
257 // Failed to init libproxy so report this before exit
258 fprintf(stdout, "F\n");
259 fflush(stdout);
260 pause();
261 }
262 eina_shutdown();
263 return 0;
264}
diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c
index 58e0805..dd641da 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -68,15 +68,11 @@ EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = 0;
68static int _ecore_con_init_count = 0; 68static int _ecore_con_init_count = 0;
69int _ecore_con_log_dom = -1; 69int _ecore_con_log_dom = -1;
70 70
71typedef struct pxProxyFactory_ pxProxyFactory; 71Eina_Bool _efl_net_proxy_helper_can_do (void);
72typedef struct _Ecore_Con_Libproxy { 72int _efl_net_proxy_helper_url_req_send(const char *url);
73 pxProxyFactory *factory; 73char **_efl_net_proxy_helper_url_wait (int id);
74 char **(*px_proxy_factory_get_proxies)(pxProxyFactory *factory, const char *url); 74void _efl_net_proxy_helper_init (void);
75 void *(*px_proxy_factory_new)(void); 75void _efl_net_proxy_helper_shutdown (void);
76 void (*px_proxy_factory_free)(pxProxyFactory *);
77 Eina_Module *mod;
78} Ecore_Con_Libproxy;
79static Ecore_Con_Libproxy _ecore_con_libproxy;
80 76
81EAPI int 77EAPI int
82ecore_con_init(void) 78ecore_con_init(void)
@@ -100,6 +96,8 @@ ecore_con_init(void)
100 goto ecore_con_log_error; 96 goto ecore_con_log_error;
101 } 97 }
102 98
99 _efl_net_proxy_helper_init();
100
103 ecore_con_mempool_init(); 101 ecore_con_mempool_init();
104 ecore_con_legacy_init(); 102 ecore_con_legacy_init();
105 103
@@ -145,16 +143,7 @@ ecore_con_shutdown(void)
145 if (--_ecore_con_init_count != 0) 143 if (--_ecore_con_init_count != 0)
146 return _ecore_con_init_count; 144 return _ecore_con_init_count;
147 145
148 if (_ecore_con_libproxy.factory) 146 _efl_net_proxy_helper_shutdown();
149 {
150 _ecore_con_libproxy.px_proxy_factory_free(_ecore_con_libproxy.factory);
151 _ecore_con_libproxy.factory = NULL;
152 }
153 if (_ecore_con_libproxy.mod)
154 {
155 eina_module_free(_ecore_con_libproxy.mod);
156 _ecore_con_libproxy.mod = NULL;
157 }
158 147
159 eina_log_timing(_ecore_con_log_dom, 148 eina_log_timing(_ecore_con_log_dom,
160 EINA_LOG_STATE_START, 149 EINA_LOG_STATE_START,
@@ -2079,12 +2068,8 @@ _efl_net_ip_connect_async_run(void *data, Ecore_Thread *thread EINA_UNUSED)
2079 2068
2080 proxy = d->proxy; 2069 proxy = d->proxy;
2081 2070
2082 if ((!proxy) && (_ecore_con_libproxy.factory)) 2071 if ((!proxy) && _efl_net_proxy_helper_can_do())
2083 { 2072 {
2084 /* libproxy is thread-safe but not cancellable. the provided
2085 * parameter must be a URL with schema, otherwise it won't
2086 * return anything.
2087 */
2088 Eina_Stringshare *url; 2073 Eina_Stringshare *url;
2089 2074
2090 url = eina_stringshare_printf("%s://%s:%s", d->protocol == IPPROTO_UDP ? "udp" : "tcp", host, port); 2075 url = eina_stringshare_printf("%s://%s:%s", d->protocol == IPPROTO_UDP ? "udp" : "tcp", host, port);
@@ -2608,64 +2593,12 @@ efl_net_udp_datagram_size_query(SOCKET fd)
2608 return READBUFSIZ; 2593 return READBUFSIZ;
2609} 2594}
2610 2595
2611Eina_Bool
2612ecore_con_libproxy_init(void)
2613{
2614 if (!_ecore_con_libproxy.mod)
2615 {
2616#define LOAD(x) \
2617 if (!_ecore_con_libproxy.mod) { \
2618 _ecore_con_libproxy.mod = eina_module_new(x); \
2619 if (_ecore_con_libproxy.mod) { \
2620 if (!eina_module_load(_ecore_con_libproxy.mod)) { \
2621 eina_module_free(_ecore_con_libproxy.mod); \
2622 _ecore_con_libproxy.mod = NULL; \
2623 } \
2624 } \
2625 }
2626#if defined(_WIN32) || defined(__CYGWIN__)
2627 LOAD("libproxy-1.dll");
2628 LOAD("libproxy.dll");
2629#elif defined(__APPLE__) && defined(__MACH__)
2630 LOAD("libproxy.1.dylib");
2631 LOAD("libproxy.dylib");
2632#else
2633 LOAD("libproxy.so.1");
2634 LOAD("libproxy.so");
2635#endif
2636#undef LOAD
2637 if (!_ecore_con_libproxy.mod)
2638 {
2639 DBG("Couldn't find libproxy in your system. Continue without it");
2640 return EINA_FALSE;
2641 }
2642
2643#define SYM(x) \
2644 if ((_ecore_con_libproxy.x = eina_module_symbol_get(_ecore_con_libproxy.mod, #x)) == NULL) { \
2645 ERR("libproxy (%s) missing symbol %s", eina_module_file_get(_ecore_con_libproxy.mod), #x); \
2646 eina_module_free(_ecore_con_libproxy.mod); \
2647 _ecore_con_libproxy.mod = NULL; \
2648 return EINA_FALSE; \
2649 }
2650
2651 SYM(px_proxy_factory_new);
2652 SYM(px_proxy_factory_free);
2653 SYM(px_proxy_factory_get_proxies);
2654#undef SYM
2655 DBG("using libproxy=%s", eina_module_file_get(_ecore_con_libproxy.mod));
2656 }
2657
2658 if (!_ecore_con_libproxy.factory)
2659 _ecore_con_libproxy.factory = _ecore_con_libproxy.px_proxy_factory_new();
2660
2661 return !!_ecore_con_libproxy.factory;
2662}
2663
2664char ** 2596char **
2665ecore_con_libproxy_proxies_get(const char *url) 2597ecore_con_libproxy_proxies_get(const char *url)
2666{ 2598{
2667 EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_con_libproxy.px_proxy_factory_get_proxies, NULL); 2599 int id = _efl_net_proxy_helper_url_req_send(url);
2668 return _ecore_con_libproxy.px_proxy_factory_get_proxies(_ecore_con_libproxy.factory, url); 2600 if (id < 0) return NULL;
2601 return _efl_net_proxy_helper_url_wait(id);
2669} 2602}
2670 2603
2671void 2604void
diff --git a/src/lib/ecore_con/ecore_con_private.h b/src/lib/ecore_con/ecore_con_private.h
index bcc9dea..42f6ded 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -93,7 +93,6 @@ extern int sd_fd_max;
93#endif 93#endif
94 94
95/* init must be called from main thread */ 95/* init must be called from main thread */
96Eina_Bool ecore_con_libproxy_init(void);
97void ecore_con_libproxy_proxies_free(char **proxies); 96void ecore_con_libproxy_proxies_free(char **proxies);
98/* BLOCKING! should be called from a worker thread */ 97/* BLOCKING! should be called from a worker thread */
99char **ecore_con_libproxy_proxies_get(const char *url); 98char **ecore_con_libproxy_proxies_get(const char *url);
diff --git a/src/lib/ecore_con/ecore_con_proxy_helper.c b/src/lib/ecore_con/ecore_con_proxy_helper.c
new file mode 100644
index 0000000..eda91e9
--- /dev/null
+++ b/src/lib/ecore_con/ecore_con_proxy_helper.c
@@ -0,0 +1,427 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <errno.h>
10#include <unistd.h>
11#include <fcntl.h>
12
13#ifdef HAVE_EVIL
14# include <Evil.h>
15#endif
16
17#include "Ecore.h"
18#include "ecore_private.h"
19#include "Ecore_Con.h"
20#include "ecore_con_private.h"
21
22typedef struct {
23 Eina_Thread_Queue *thq;
24 char *str;
25 char **proxies;
26 int id;
27 int busy;
28} Efl_Net_Proxy_Helper_Req;
29
30typedef struct {
31 Eina_Thread_Queue_Msg head;
32 char **proxies;
33} Efl_Net_Proxy_Helper_Thq_Msg;
34
35static Eina_Bool _efl_net_proxy_helper_works = EINA_TRUE;
36static Ecore_Exe *_efl_net_proxy_helper_exe = NULL;
37static Eina_Prefix *_efl_net_proxy_helper_prefix = NULL;
38static Eina_Spinlock _efl_net_proxy_helper_queue_lock;
39static int _efl_net_proxy_helper_req_id = 0;
40static Eina_List *_efl_net_proxy_helper_queue = NULL;
41static Ecore_Event_Handler *_efl_net_proxy_helper_handler_exe_del = NULL;
42static Ecore_Event_Handler *_efl_net_proxy_helper_handler_exe_data = NULL;
43static Eina_Bool _efl_net_proxy_helper_queue_lock_init = EINA_FALSE;
44static int _efl_net_proxy_helper_init_num = 0;
45
46static int locks = 0;
47
48#ifdef _WIN32
49# define HELPER_EXT ".exe"
50#else
51# define HELPER_EXT
52#endif
53
54static void
55_efl_net_proxy_helper_spawn(void)
56{
57 char buf[PATH_MAX];
58 Eina_List *l;
59 Efl_Net_Proxy_Helper_Req *req;
60 static int run_in_tree = -1;
61
62 if (!_efl_net_proxy_helper_works) return;
63 if (_efl_net_proxy_helper_exe) return;
64 if (run_in_tree == -1)
65 {
66 run_in_tree = 0;
67#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
68 if (getuid() == geteuid())
69#endif
70 {
71 if (getenv("EFL_RUN_IN_TREE")) run_in_tree = 1;
72 }
73 }
74 // find binary location path
75 if (run_in_tree == 1)
76 snprintf
77 (buf, sizeof(buf),
78 PACKAGE_BUILD_DIR"/src/bin/ecore_con/utils/efl_net_proxy_helper"HELPER_EXT);
79 else
80 snprintf
81 (buf, sizeof(buf),
82 "%s/ecore_con/utils/"MODULE_ARCH"/efl_net_proxy_helper"HELPER_EXT,
83 eina_prefix_lib_get(_efl_net_proxy_helper_prefix));
84 // run it with stdin/out piped line buffered with events
85 _efl_net_proxy_helper_exe = ecore_exe_pipe_run
86 (buf,
87 ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
88 ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_TERM_WITH_PARENT |
89 ECORE_EXE_NOT_LEADER, NULL);
90 // resend unhandled requests
91 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
92 {
93 locks++;
94 EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
95 ecore_exe_send(_efl_net_proxy_helper_exe,
96 req->str, strlen(req->str));
97 locks--;
98 }
99 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
100}
101
102static void
103_efl_net_proxy_helper_kill(void)
104{
105 if (!_efl_net_proxy_helper_exe) return;
106 // don't exit if anything is pending
107 if (_efl_net_proxy_helper_queue) return;
108 ecore_exe_kill(_efl_net_proxy_helper_exe);
109 ecore_exe_free(_efl_net_proxy_helper_exe);
110 _efl_net_proxy_helper_exe = NULL;
111}
112
113static void
114_efl_net_proxy_helper_cancel(void)
115{
116 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
117 {
118 locks++;
119 Efl_Net_Proxy_Helper_Req *req;
120
121 EINA_LIST_FREE(_efl_net_proxy_helper_queue, req)
122 {
123 Efl_Net_Proxy_Helper_Thq_Msg *msg;
124 void *ref;
125
126 msg = eina_thread_queue_send
127 (req->thq, sizeof(Efl_Net_Proxy_Helper_Thq_Msg), &ref);
128 msg->proxies = NULL;
129 eina_thread_queue_send_done(req->thq, ref);
130 if (!req->busy)
131 {
132 free(req->str);
133 ecore_con_libproxy_proxies_free(req->proxies);
134 eina_thread_queue_free(req->thq);
135 free(req);
136 }
137 }
138 locks--;
139 }
140 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
141}
142
143static void
144_efl_net_proxy_helper_proxy_add(int id, const char *url)
145{
146 Eina_List *l;
147 Efl_Net_Proxy_Helper_Req *req;
148
149 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
150 {
151 locks++;
152 EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
153 {
154 if (req->id == id) break;
155 req = NULL;
156 }
157 if (req)
158 {
159 if (url)
160 {
161 char **proxies = req->proxies;
162 int n = 0;
163
164 if (proxies)
165 {
166 for (n = 0; proxies[n]; n++);
167 }
168 n++;
169 proxies = realloc(proxies, sizeof(char *) * (n + 1));
170 if (proxies)
171 {
172 req->proxies = proxies;
173 proxies[n - 1] = strdup(url);
174 proxies[n] = NULL;
175 }
176 }
177 else
178 {
179 Efl_Net_Proxy_Helper_Thq_Msg *msg;
180 void *ref;
181
182 msg = eina_thread_queue_send
183 (req->thq, sizeof(Efl_Net_Proxy_Helper_Thq_Msg), &ref);
184 msg->proxies = req->proxies;
185 req->proxies = NULL;
186 eina_thread_queue_send_done(req->thq, ref);
187 }
188 }
189 locks--;
190 }
191 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
192}
193
194static Eina_Bool
195_efl_net_proxy_helper_cb_exe_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *info)
196{
197 Ecore_Exe_Event_Del *event = info;
198
199 if (!_efl_net_proxy_helper_exe) return EINA_TRUE;
200 if (event->exe == _efl_net_proxy_helper_exe)
201 {
202 static double last_respawn = 0.0;
203 double t;
204 Eina_Bool respawn = EINA_FALSE;
205
206 t = ecore_time_get();
207 _efl_net_proxy_helper_exe = NULL;
208 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
209 {
210 locks++;
211 if (_efl_net_proxy_helper_queue)
212 {
213 if ((t - last_respawn) > 5.0) respawn = EINA_TRUE;
214 }
215 locks--;
216 }
217 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
218 if (respawn)
219 {
220 last_respawn = t;
221 _efl_net_proxy_helper_spawn();
222 }
223 return EINA_FALSE;
224 }
225 return EINA_TRUE;
226}
227
228static Eina_Bool
229_efl_net_proxy_helper_cb_exe_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *info)
230{
231 Ecore_Exe_Event_Data *event = info;
232
233 if (!_efl_net_proxy_helper_exe) return EINA_TRUE;
234 if (event->exe == _efl_net_proxy_helper_exe)
235 {
236 if (event->lines)
237 {
238 int i;
239
240 for (i = 0; event->lines[i].line; i++)
241 {
242 char *line = event->lines[i].line;
243
244 if (line[0] == 'F') // failure
245 {
246 _efl_net_proxy_helper_works = EINA_FALSE;
247 _efl_net_proxy_helper_cancel();
248 _efl_net_proxy_helper_kill();
249 }
250 else if ((line[0] == 'P') && (line[1] == ' ')) // proxy
251 {
252 int id = atoi(line + 2);
253 char *p, *url = NULL;
254
255 for (p = line + 2; *p && (*p != ' '); p++);
256 if ((p[0] == ' ') && (p[1] == 'P') && (p[2] == ' '))
257 url = p + 3;
258 else if ((p[0] == ' ') && (p[1] == 'E'))
259 url = NULL;
260 _efl_net_proxy_helper_proxy_add(id, url);
261 }
262 }
263 }
264 return EINA_FALSE;
265 }
266 return EINA_TRUE;
267}
268
269Eina_Bool
270_efl_net_proxy_helper_can_do(void)
271{
272 return _efl_net_proxy_helper_works;
273}
274
275
276static void
277_efl_net_proxy_helper_cb_send_do(void *data)
278{
279 char *str = data;
280 if (!str) return;
281 // spawn exe if needed
282 if (!_efl_net_proxy_helper_exe) _efl_net_proxy_helper_spawn();
283 if (_efl_net_proxy_helper_exe)
284 ecore_exe_send(_efl_net_proxy_helper_exe, str, strlen(str));
285 free(str);
286}
287
288int
289_efl_net_proxy_helper_url_req_send(const char *url)
290{
291 char *buf;
292 int id = -1;
293 Efl_Net_Proxy_Helper_Req *req;
294
295 if (!_efl_net_proxy_helper_works) return -1;
296 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
297 {
298 locks++;
299 // new id - just an int that eventually loops.
300 _efl_net_proxy_helper_req_id++;
301 if (_efl_net_proxy_helper_req_id >= ((1 << 30) - 1))
302 _efl_net_proxy_helper_req_id = 1;
303 id = _efl_net_proxy_helper_req_id;
304 locks--;
305 }
306 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
307 // create request to quque up to look up responses for
308 req = calloc(1, sizeof(Efl_Net_Proxy_Helper_Req));
309 if (!req) return -1;
310 req->id = id;
311 req->thq = eina_thread_queue_new();
312 if (!req->thq)
313 {
314 free(req);
315 return -1;
316 }
317 buf = alloca(strlen(url) + 256);
318 sprintf(buf, "P %i %s\n", req->id, url);
319 req->str = strdup(buf);
320 if (!req->str)
321 {
322 eina_thread_queue_free(req->thq);
323 free(req);
324 return -1;
325 }
326 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
327 {
328 locks++;
329 _efl_net_proxy_helper_queue =
330 eina_list_append(_efl_net_proxy_helper_queue, req);
331 locks--;
332 }
333 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
334 // actually send the req now i'ts queued
335 ecore_main_loop_thread_safe_call_async
336 (_efl_net_proxy_helper_cb_send_do, strdup(buf));
337 return id;
338}
339
340char **
341_efl_net_proxy_helper_url_wait(int id)
342{
343 Eina_List *l;
344 Efl_Net_Proxy_Helper_Req *req;
345 Efl_Net_Proxy_Helper_Thq_Msg *msg;
346 void *ref;
347 char **ret = NULL;
348
349 if (id < 0) return NULL;
350 if (!_efl_net_proxy_helper_exe) return NULL;
351 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
352 {
353 locks++;
354 EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
355 {
356 if (req->id == id) break;
357 req = NULL;
358 }
359 if (!req) goto end;
360 req->busy++;
361 locks--;
362 }
363 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
364
365 msg = eina_thread_queue_wait(req->thq, &ref);
366 ret = msg->proxies;
367 msg->proxies = NULL;
368 eina_thread_queue_wait_done(req->thq, ref);
369
370 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
371 {
372 locks++;
373 free(req->str);
374 ecore_con_libproxy_proxies_free(req->proxies);
375 eina_thread_queue_free(req->thq);
376 _efl_net_proxy_helper_queue =
377 eina_list_remove(_efl_net_proxy_helper_queue, req);
378 free(req);
379 }
380end:
381 locks--;
382 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
383 return ret;
384}
385
386void
387_efl_net_proxy_helper_init(void)
388{
389 _efl_net_proxy_helper_init_num++;
390 if (_efl_net_proxy_helper_init_num > 1) return;
391 if (_efl_net_proxy_helper_prefix) return;
392 _efl_net_proxy_helper_prefix = eina_prefix_new
393 (NULL, ecore_con_init, "ECORE", "ecore", "checkme",
394 PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
395 if (!_efl_net_proxy_helper_queue_lock_init)
396 {
397 eina_spinlock_new(&_efl_net_proxy_helper_queue_lock);
398 _efl_net_proxy_helper_queue_lock_init = EINA_TRUE;
399 }
400 _efl_net_proxy_helper_handler_exe_del =
401 ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
402 _efl_net_proxy_helper_cb_exe_del, NULL);
403 _efl_net_proxy_helper_handler_exe_data =
404 ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
405 _efl_net_proxy_helper_cb_exe_data, NULL);
406}
407
408void
409_efl_net_proxy_helper_shutdown(void)
410{
411 _efl_net_proxy_helper_init_num--;
412 if (_efl_net_proxy_helper_init_num > 0) return;
413 if (!_efl_net_proxy_helper_prefix) return;
414 if (_efl_net_proxy_helper_exe)
415 {
416 _efl_net_proxy_helper_cancel();
417 _efl_net_proxy_helper_kill();
418 }
419 eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
420 eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
421 eina_prefix_free(_efl_net_proxy_helper_prefix);
422 _efl_net_proxy_helper_prefix = NULL;
423 ecore_event_handler_del(_efl_net_proxy_helper_handler_exe_del);
424 _efl_net_proxy_helper_handler_exe_del = NULL;
425 ecore_event_handler_del(_efl_net_proxy_helper_handler_exe_data);
426 _efl_net_proxy_helper_handler_exe_data = NULL;
427}
diff --git a/src/lib/ecore_con/efl_net_dialer_http.c b/src/lib/ecore_con/efl_net_dialer_http.c
index b4d39e4..b5fe3e4 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.c
+++ b/src/lib/ecore_con/efl_net_dialer_http.c
@@ -1380,7 +1380,7 @@ _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, co
1380#undef IS_HEADER 1380#undef IS_HEADER
1381 } 1381 }
1382 1382
1383 if ((!pd->proxy) && (ecore_con_libproxy_init())) 1383 if (!pd->proxy)
1384 { 1384 {
1385 Efl_Net_Dialer_Http_Libproxy_Context *ctx; 1385 Efl_Net_Dialer_Http_Libproxy_Context *ctx;
1386 1386