summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-09-19 10:00:36 -0300
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-09-19 10:01:51 -0300
commit8550a33b27b35065b4f5bd6defbece003e1af0de (patch)
tree76bc6e75ad86a1f01cd27e5f7d3d6a75773ffb70 /src
parent0d478c301f49fccfd94a107c060696f79490c30d (diff)
efl_net_dialer_http: use libproxy.
query libproxy in a thread (since it's nasty and blocks), then apply proxy to curl and execute the request.
Diffstat (limited to 'src')
-rw-r--r--src/lib/ecore_con/efl_net_dialer_http.c146
1 files changed, 137 insertions, 9 deletions
diff --git a/src/lib/ecore_con/efl_net_dialer_http.c b/src/lib/ecore_con/efl_net_dialer_http.c
index 1e7fd549c0..1b5b20bfc9 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.c
+++ b/src/lib/ecore_con/efl_net_dialer_http.c
@@ -181,6 +181,9 @@ typedef struct
181 Eina_Stringshare *address_remote; 181 Eina_Stringshare *address_remote;
182 Eina_Stringshare *method; 182 Eina_Stringshare *method;
183 Eina_Stringshare *user_agent; 183 Eina_Stringshare *user_agent;
184#ifdef HAVE_LIBPROXY
185 Ecore_Thread *libproxy_thread;
186#endif
184 struct { 187 struct {
185 struct curl_slist *headers; 188 struct curl_slist *headers;
186 int64_t content_length; 189 int64_t content_length;
@@ -1166,6 +1169,13 @@ _efl_net_dialer_http_efl_object_constructor(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1166EOLIAN static void 1169EOLIAN static void
1167_efl_net_dialer_http_efl_object_destructor(Eo *o, Efl_Net_Dialer_Http_Data *pd) 1170_efl_net_dialer_http_efl_object_destructor(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1168{ 1171{
1172#ifdef HAVE_LIBPROXY
1173 if (pd->libproxy_thread)
1174 {
1175 ecore_thread_cancel(pd->libproxy_thread);
1176 pd->libproxy_thread = NULL;
1177 }
1178#endif
1169 if (pd->in_curl_callback) 1179 if (pd->in_curl_callback)
1170 { 1180 {
1171 DBG("deleting HTTP dialer=%p from CURL callback.", o); 1181 DBG("deleting HTTP dialer=%p from CURL callback.", o);
@@ -1234,10 +1244,99 @@ _efl_net_dialer_http_efl_object_destructor(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1234 _secure_free(&pd->authentication.password); 1244 _secure_free(&pd->authentication.password);
1235} 1245}
1236 1246
1247static void
1248_efl_net_dialer_http_curl_start(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1249{
1250 Efl_Net_Dialer_Http_Curlm *cm;
1251
1252 // TODO: move this to be per-loop once multiple mainloops are supported
1253 // this would need to attach something to the loop
1254 cm = &_cm_global;
1255 if (!cm->loop) cm->loop = efl_loop_user_loop_get(o);
1256 if (!_efl_net_dialer_http_curlm_add(cm, o, pd->easy))
1257 {
1258 ERR("dialer=%p could not add curl easy handle to multi manager", o);
1259 return;
1260 }
1261
1262 pd->cm = cm;
1263 DBG("started curl request easy=%p, cm=%p", pd->easy, pd->cm);
1264}
1265
1266#ifdef HAVE_LIBPROXY
1267typedef struct _Efl_Net_Dialer_Http_Libproxy_Context {
1268 Eo *o;
1269 char *url;
1270 char *proxy;
1271} Efl_Net_Dialer_Http_Libproxy_Context;
1272
1273static void
1274_efl_net_dialer_http_libproxy_run(void *data, Ecore_Thread *thread EINA_UNUSED)
1275{
1276 Efl_Net_Dialer_Http_Libproxy_Context *ctx = data;
1277 char **proxies = px_proxy_factory_get_proxies(_ecore_con_libproxy_factory, ctx->url);
1278 char **itr;
1279
1280 if (!proxies) return;
1281
1282 for (itr = proxies; *itr != NULL; itr++)
1283 {
1284 if (itr != proxies) free(*itr);
1285 else
1286 {
1287 if (strcmp(*itr, "direct://") != 0) ctx->proxy = *itr;
1288 else
1289 {
1290 /* NULL not "" so we let curl use envvars */
1291 ctx->proxy = NULL;
1292 free(*itr);
1293 }
1294 }
1295 }
1296 free(proxies);
1297}
1298
1299static void
1300_efl_net_dialer_http_libproxy_context_free(Efl_Net_Dialer_Http_Libproxy_Context *ctx)
1301{
1302 free(ctx->proxy);
1303 free(ctx->url);
1304 free(ctx);
1305}
1306
1307static void
1308_efl_net_dialer_http_libproxy_end(void *data, Ecore_Thread *thread EINA_UNUSED)
1309{
1310 Efl_Net_Dialer_Http_Libproxy_Context *ctx = data;
1311 Eo *o = ctx->o;
1312 Efl_Net_Dialer_Http_Data *pd = efl_data_scope_get(o, MY_CLASS);
1313
1314 if (ctx->proxy)
1315 {
1316 CURLcode r = curl_easy_setopt(pd->easy, CURLOPT_PROXY, ctx->proxy);
1317 if (r != CURLE_OK)
1318 ERR("dialer=%p could not set proxy to '%s': %s",
1319 o, ctx->proxy, curl_easy_strerror(r));
1320 else
1321 DBG("libproxy said %s for %s", ctx->proxy, pd->address_dial);
1322 }
1323
1324 _efl_net_dialer_http_libproxy_context_free(ctx);
1325
1326 _efl_net_dialer_http_curl_start(o, pd);
1327}
1328
1329static void
1330_efl_net_dialer_http_libproxy_cancel(void *data, Ecore_Thread *thread EINA_UNUSED)
1331{
1332 Efl_Net_Dialer_Http_Libproxy_Context *ctx = data;
1333 _efl_net_dialer_http_libproxy_context_free(ctx);
1334}
1335#endif
1336
1237EOLIAN static Eina_Error 1337EOLIAN static Eina_Error
1238_efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, const char *address) 1338_efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, const char *address)
1239{ 1339{
1240 Efl_Net_Dialer_Http_Curlm *cm;
1241 CURLcode r; 1340 CURLcode r;
1242 1341
1243 EINA_SAFETY_ON_NULL_RETURN_VAL(address, EINVAL); 1342 EINA_SAFETY_ON_NULL_RETURN_VAL(address, EINVAL);
@@ -1258,17 +1357,46 @@ _efl_net_dialer_http_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Http_Data *pd, co
1258 return EINVAL; 1357 return EINVAL;
1259 } 1358 }
1260 1359
1261 // TODO: move this to be per-loop once multiple mainloops are supported 1360#ifdef HAVE_LIBPROXY
1262 // this would need to attach something to the loop 1361 if (!pd->proxy)
1263 cm = &_cm_global;
1264 if (!cm->loop) cm->loop = efl_loop_user_loop_get(o);
1265 if (!_efl_net_dialer_http_curlm_add(cm, o, pd->easy))
1266 { 1362 {
1267 ERR("dialer=%p could not add curl easy handle to multi manager", o); 1363 Efl_Net_Dialer_Http_Libproxy_Context *ctx;
1268 return ENOSYS; 1364
1365 if (!_ecore_con_libproxy_factory)
1366 _ecore_con_libproxy_factory = px_proxy_factory_new();
1367
1368 if (pd->libproxy_thread)
1369 ecore_thread_cancel(pd->libproxy_thread);
1370
1371 ctx = calloc(1, sizeof(Efl_Net_Dialer_Http_Libproxy_Context));
1372 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, ENOMEM);
1373
1374 if (strstr(address, "://")) ctx->url = strdup(address);
1375 else
1376 {
1377 ctx->url = malloc(strlen("http://") + strlen(address) + 1);
1378 if (ctx->url)
1379 {
1380 memcpy(ctx->url, "http://", strlen("http://"));
1381 memcpy(ctx->url + strlen("http://"), address, strlen(address) + 1);
1382 }
1383 }
1384 EINA_SAFETY_ON_NULL_GOTO(ctx->url, url_error);
1385
1386 ctx->o = o;
1387
1388 pd->libproxy_thread = ecore_thread_run(_efl_net_dialer_http_libproxy_run,
1389 _efl_net_dialer_http_libproxy_end,
1390 _efl_net_dialer_http_libproxy_cancel,
1391 ctx);
1392 return 0;
1393 url_error:
1394 free(ctx);
1395 return ENOMEM;
1269 } 1396 }
1397#endif
1270 1398
1271 pd->cm = cm; 1399 _efl_net_dialer_http_curl_start(o, pd);
1272 1400
1273 DBG("HTTP dialer=%p, curl_easy=%p, address='%s'", 1401 DBG("HTTP dialer=%p, curl_easy=%p, address='%s'",
1274 o, pd->easy, pd->address_dial); 1402 o, pd->easy, pd->address_dial);