aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-07-14 15:43:42 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-07-14 15:43:42 +0000
commitf8976258f12b4639d868c02053f88c2c1e8a6e50 (patch)
tree5eb14c1873dfb4c43d31bc4b90e54cfb9deaf5e9 /src
parent7e29d78478948cfabc8cb207c3b3538b4c28a6d6 (diff)
downloadgnunet-f8976258f12b4639d868c02053f88c2c1e8a6e50.tar.gz
gnunet-f8976258f12b4639d868c02053f88c2c1e8a6e50.zip
-urlencode post working, performance, replace location hdr val
Diffstat (limited to 'src')
-rw-r--r--src/gns/gnunet-gns-proxy.c208
1 files changed, 172 insertions, 36 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index f568a16e8..8ebc4bfc6 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -286,6 +286,8 @@ struct ProxyCurlTask
286 /* post data */ 286 /* post data */
287 struct ProxyPostData *post_data_head; 287 struct ProxyPostData *post_data_head;
288 struct ProxyPostData *post_data_tail; 288 struct ProxyPostData *post_data_tail;
289
290 int post_done;
289 291
290}; 292};
291 293
@@ -348,11 +350,14 @@ struct ProxyPostData
348 /* DLL */ 350 /* DLL */
349 struct ProxyPostData *prev; 351 struct ProxyPostData *prev;
350 352
351 /* key */
352 char *key;
353
354 /* value */ 353 /* value */
355 char *value; 354 char *value;
355
356 /* to copy */
357 size_t bytes_left;
358
359 /* size */
360 size_t total_bytes;
356}; 361};
357 362
358 363
@@ -501,6 +506,7 @@ con_post_data_iter (void *cls,
501{ 506{
502 struct ProxyCurlTask* ctask = cls; 507 struct ProxyCurlTask* ctask = cls;
503 struct ProxyPostData* pdata; 508 struct ProxyPostData* pdata;
509 char* enc;
504 510
505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
506 "Got POST data: '%s : %s' at offset %llu size %lld\n", 512 "Got POST data: '%s : %s' at offset %llu size %lld\n",
@@ -508,18 +514,49 @@ con_post_data_iter (void *cls,
508 514
509 /* FIXME ! if transfer enc == urlenc! */ 515 /* FIXME ! if transfer enc == urlenc! */
510 516
517 if (0 == off)
518 {
519 /* a key */
520 pdata = GNUNET_malloc (sizeof (struct ProxyPostData));
521 enc = escape_to_urlenc (key);
522 pdata->value = GNUNET_malloc (strlen (enc) + 3);
523 if (NULL != ctask->post_data_head)
524 {
525 pdata->value[0] = '&';
526 memcpy (pdata->value+1, enc, strlen (enc));
527 }
528 else
529 memcpy (pdata->value, enc, strlen (enc));
530 pdata->value[strlen (pdata->value)] = '=';
531 pdata->bytes_left = strlen (pdata->value);
532 pdata->total_bytes = pdata->bytes_left;
533 GNUNET_free (enc);
534
535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
536 "Escaped POST key: '%s'\n",
537 pdata->value);
538
539 GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
540 ctask->post_data_tail,
541 pdata);
542 }
543
544 /* a value */
511 pdata = GNUNET_malloc (sizeof (struct ProxyPostData)); 545 pdata = GNUNET_malloc (sizeof (struct ProxyPostData));
512 pdata->key = escape_to_urlenc (key); 546 enc = escape_to_urlenc (data);
513 pdata->value = escape_to_urlenc (data); 547 pdata->value = GNUNET_malloc (strlen (enc) + 1);
548 memcpy (pdata->value, enc, strlen (enc));
549 pdata->bytes_left = strlen (pdata->value);
550 pdata->total_bytes = pdata->bytes_left;
551 GNUNET_free (enc);
514 552
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
516 "Escaped POST data: '%s : %s'\n", 554 "Escaped POST value: '%s'\n",
517 pdata->key, pdata->value); 555 pdata->value);
518 556
519 GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head, 557 GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
520 ctask->post_data_tail, 558 ctask->post_data_tail,
521 pdata); 559 pdata);
522
523 return MHD_YES; 560 return MHD_YES;
524} 561}
525 562
@@ -618,6 +655,9 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
618 char hdr_mime[html_mime_len+1]; 655 char hdr_mime[html_mime_len+1];
619 char hdr_generic[bytes+1]; 656 char hdr_generic[bytes+1];
620 char new_cookie_hdr[bytes+strlen (ctask->leho)+1]; 657 char new_cookie_hdr[bytes+strlen (ctask->leho)+1];
658 char new_location[MAX_HTTP_URI_LENGTH+500];
659 char real_host[264];
660 char leho_host[264];
621 char* ndup; 661 char* ndup;
622 char* tok; 662 char* tok;
623 char* cookie_domain; 663 char* cookie_domain;
@@ -759,18 +799,40 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
759 return bytes; 799 return bytes;
760 } 800 }
761 801
802 hdr_val++;
803
804 if (0 == strcasecmp (MHD_HTTP_HEADER_LOCATION, hdr_type))
805 {
806 if (ctask->mhd->is_ssl)
807 {
808 sprintf (leho_host, "https://%s", ctask->leho);
809 sprintf (real_host, "https://%s", ctask->host);
810 }
811 else
812 {
813 sprintf (leho_host, "http://%s", ctask->leho);
814 sprintf (real_host, "http://%s", ctask->host);
815 }
816
817 if (0 == memcmp (leho_host, hdr_val, strlen (leho_host)))
818 {
819 sprintf (new_location, "%s%s", real_host, hdr_val+strlen (leho_host));
820 hdr_val = new_location;
821 }
822 }
823
762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
763 "Trying to set %s: %s\n", 825 "Trying to set %s: %s\n",
764 hdr_type, 826 hdr_type,
765 hdr_val+1); 827 hdr_val);
766 if (GNUNET_NO == MHD_add_response_header (ctask->response, 828 if (GNUNET_NO == MHD_add_response_header (ctask->response,
767 hdr_type, 829 hdr_type,
768 hdr_val+1)) 830 hdr_val))
769 { 831 {
770 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 832 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
771 "MHD: Error adding %s header field %s\n", 833 "MHD: Error adding %s header field %s\n",
772 hdr_type, 834 hdr_type,
773 hdr_val+1); 835 hdr_val);
774 } 836 }
775 GNUNET_free (ndup); 837 GNUNET_free (ndup);
776 return bytes; 838 return bytes;
@@ -876,8 +938,8 @@ mhd_content_cb (void *cls,
876 938
877 if ((GNUNET_YES == ctask->download_is_finished) && 939 if ((GNUNET_YES == ctask->download_is_finished) &&
878 (GNUNET_NO == ctask->download_error) && 940 (GNUNET_NO == ctask->download_error) &&
879 (0 == bytes_to_copy) && 941 (0 == bytes_to_copy)) /* &&
880 (BUF_WAIT_FOR_CURL == ctask->buf_status)) 942 (BUF_WAIT_FOR_CURL == ctask->buf_status))*/
881 { 943 {
882 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 944 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
883 "MHD: sending response for %s\n", ctask->url); 945 "MHD: sending response for %s\n", ctask->url);
@@ -890,8 +952,8 @@ mhd_content_cb (void *cls,
890 952
891 if ((GNUNET_YES == ctask->download_error) && 953 if ((GNUNET_YES == ctask->download_error) &&
892 (GNUNET_YES == ctask->download_is_finished) && 954 (GNUNET_YES == ctask->download_is_finished) &&
893 (0 == bytes_to_copy) && 955 (0 == bytes_to_copy)) /* &&
894 (BUF_WAIT_FOR_CURL == ctask->buf_status)) 956 (BUF_WAIT_FOR_CURL == ctask->buf_status))*/
895 { 957 {
896 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 958 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
897 "MHD: sending error response\n"); 959 "MHD: sending error response\n");
@@ -1180,6 +1242,68 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx)
1180} 1242}
1181 1243
1182/** 1244/**
1245 * cURL callback for post data
1246 */
1247static size_t
1248read_callback (void *buf, size_t size, size_t nmemb, void *cls)
1249{
1250 struct ProxyCurlTask *ctask = cls;
1251 struct ProxyPostData *pdata = ctask->post_data_head;
1252 size_t len = size * nmemb;
1253 size_t to_copy;
1254 char* pos;
1255 char tmp[2048];
1256
1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1258 "CURL: read callback\n");
1259
1260 if (NULL == pdata)
1261 return 0;
1262
1263 //fin
1264 if (NULL == pdata->value)
1265 {
1266 return 0;
1267 if (len < 2)
1268 return 0;
1269
1270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1271 "CURL: Terminating POST data\n");
1272
1273 memcpy (buf, "\n\r", 2);
1274 GNUNET_CONTAINER_DLL_remove (ctask->post_data_head,
1275 ctask->post_data_tail,
1276 pdata);
1277 GNUNET_free (pdata);
1278 return 2;
1279 }
1280
1281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1282 "CURL: read callback value %s\n", pdata->value);
1283
1284 to_copy = pdata->bytes_left;
1285 if (to_copy > len)
1286 to_copy = len;
1287
1288 pos = pdata->value + (pdata->total_bytes - pdata->bytes_left);
1289 memcpy (buf, pos, to_copy);
1290 memcpy (tmp, pos, to_copy);
1291 tmp[to_copy] = 'c';
1292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1293 "CURL: Wrote %s\n", tmp);
1294 pdata->bytes_left -= to_copy;
1295 if (pdata->bytes_left <= 0)
1296 {
1297 GNUNET_free (pdata->value);
1298 GNUNET_CONTAINER_DLL_remove (ctask->post_data_head,
1299 ctask->post_data_tail,
1300 pdata);
1301 GNUNET_free (pdata);
1302 }
1303 return to_copy;
1304}
1305
1306/**
1183 * Task that is run when we are ready to receive more data 1307 * Task that is run when we are ready to receive more data
1184 * from curl 1308 * from curl
1185 * 1309 *
@@ -1626,6 +1750,7 @@ create_response (void *cls,
1626 int ret = MHD_YES; 1750 int ret = MHD_YES;
1627 1751
1628 struct ProxyCurlTask *ctask; 1752 struct ProxyCurlTask *ctask;
1753 struct ProxyPostData *fin_post;
1629 1754
1630 //FIXME handle 1755 //FIXME handle
1631 if ((0 != strcasecmp (meth, MHD_HTTP_METHOD_GET)) && 1756 if ((0 != strcasecmp (meth, MHD_HTTP_METHOD_GET)) &&
@@ -1696,17 +1821,19 @@ create_response (void *cls,
1696 1821
1697 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) 1822 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
1698 { 1823 {
1699 if (0 == *upload_data_size) 1824 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1700 { 1825 "Setting up POST processor\n");
1701 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1826 ctask->post_handler = MHD_create_post_processor (con,
1702 "Setting up POST processor\n"); 1827 POSTBUFFERSIZE,
1703 ctask->post_handler = MHD_create_post_processor (con, 1828 &con_post_data_iter,
1704 POSTBUFFERSIZE, 1829 ctask);
1705 &con_post_data_iter,
1706 ctask);
1707 return MHD_YES;
1708 }
1709 curl_easy_setopt (ctask->curl, CURLOPT_POST, 1); 1830 curl_easy_setopt (ctask->curl, CURLOPT_POST, 1);
1831 curl_easy_setopt (ctask->curl, CURLOPT_READFUNCTION,
1832 &read_callback);
1833 curl_easy_setopt (ctask->curl, CURLOPT_READDATA, ctask);
1834 ctask->headers = curl_slist_append (ctask->headers,
1835 "Transfer-Encoding: chunked");
1836 /*curl_easy_setopt (ctask->curl, CURLOPT_POST, 1);
1710 curl_easy_setopt (ctask->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size); 1837 curl_easy_setopt (ctask->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size);
1711 curl_easy_setopt (ctask->curl, CURLOPT_COPYPOSTFIELDS, upload_data); 1838 curl_easy_setopt (ctask->curl, CURLOPT_COPYPOSTFIELDS, upload_data);
1712 1839
@@ -1714,7 +1841,7 @@ create_response (void *cls,
1714 "Got POST data: %s\n", upload_data); 1841 "Got POST data: %s\n", upload_data);
1715 curl_easy_cleanup (ctask->curl); 1842 curl_easy_cleanup (ctask->curl);
1716 GNUNET_free (ctask); 1843 GNUNET_free (ctask);
1717 return MHD_NO; 1844 return MHD_NO;*/
1718 } 1845 }
1719 1846
1720 curl_easy_setopt (ctask->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr); 1847 curl_easy_setopt (ctask->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
@@ -1754,18 +1881,27 @@ create_response (void *cls,
1754 1881
1755 ctask = (struct ProxyCurlTask *) *con_cls; 1882 ctask = (struct ProxyCurlTask *) *con_cls;
1756 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) 1883 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
1884 {
1885 if (0 != *upload_data_size)
1757 { 1886 {
1758 if (0 != *upload_data_size) 1887 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1759 { 1888 "Invoking POST processor\n");
1760 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1889 MHD_post_process (ctask->post_handler,
1761 "Invoking POST processor\n"); 1890 upload_data, *upload_data_size);
1762 MHD_post_process (ctask->post_handler, 1891 *upload_data_size = 0;
1763 upload_data, *upload_data_size); 1892 return MHD_YES;
1764 *upload_data_size = 0;
1765 return MHD_YES;
1766 }
1767 return MHD_NO;
1768 } 1893 }
1894 else if (GNUNET_NO == ctask->post_done)
1895 {
1896 fin_post = GNUNET_malloc (sizeof (struct ProxyPostData));
1897 GNUNET_CONTAINER_DLL_insert_tail (ctask->post_data_head,
1898 ctask->post_data_tail,
1899 fin_post);
1900 ctask->post_done = GNUNET_YES;
1901 return MHD_YES;
1902 }
1903 }
1904
1769 if (GNUNET_YES != ctask->ready_to_queue) 1905 if (GNUNET_YES != ctask->ready_to_queue)
1770 return MHD_YES; /* wait longer */ 1906 return MHD_YES; /* wait longer */
1771 1907