aboutsummaryrefslogtreecommitdiff
path: root/src/curl
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-05-03 16:19:17 +0200
committerChristian Grothoff <christian@grothoff.org>2019-05-03 16:19:17 +0200
commitba33155b4f60b8f8049c4f77e3b7b40e29ae63e2 (patch)
treee08efba6a4081c9976f9caa5f149a277c6420298 /src/curl
parent782565417337605572b66758bf13d7123e26f744 (diff)
downloadgnunet-ba33155b4f60b8f8049c4f77e3b7b40e29ae63e2.tar.gz
gnunet-ba33155b4f60b8f8049c4f77e3b7b40e29ae63e2.zip
reindentation
Diffstat (limited to 'src/curl')
-rw-r--r--src/curl/curl.c267
1 files changed, 106 insertions, 161 deletions
diff --git a/src/curl/curl.c b/src/curl/curl.c
index 1c352f195..e13c1478f 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -39,18 +39,24 @@
39 * @param function which function failed to run 39 * @param function which function failed to run
40 * @param code what was the curl error code 40 * @param code what was the curl error code
41 */ 41 */
42#define CURL_STRERROR(type, function, code) \ 42#define CURL_STRERROR(type, function, code) \
43 GNUNET_log (type, \ 43 GNUNET_log (type, \
44 "Curl function `%s' has failed at `%s:%d' with error: %s\n", \ 44 "Curl function `%s' has failed at `%s:%d' with error: %s\n", \
45 function, __FILE__, __LINE__, curl_easy_strerror (code)); 45 function, \
46 __FILE__, \
47 __LINE__, \
48 curl_easy_strerror (code));
46 49
47/** 50/**
48 * Print JSON parsing related error information 51 * Print JSON parsing related error information
49 */ 52 */
50#define JSON_WARN(error) \ 53#define JSON_WARN(error) \
51 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \ 54 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
52 "JSON parsing failed at %s:%u: %s (%s)\n", \ 55 "JSON parsing failed at %s:%u: %s (%s)\n", \
53 __FILE__, __LINE__, error.text, error.source) 56 __FILE__, \
57 __LINE__, \
58 error.text, \
59 error.source)
54 60
55 61
56/** 62/**
@@ -99,7 +105,6 @@ struct GNUNET_CURL_Job
99 * Buffer for response received from CURL. 105 * Buffer for response received from CURL.
100 */ 106 */
101 struct GNUNET_CURL_DownloadBuffer db; 107 struct GNUNET_CURL_DownloadBuffer db;
102
103}; 108};
104 109
105 110
@@ -156,8 +161,7 @@ struct GNUNET_CURL_Context
156 * @return library context 161 * @return library context
157 */ 162 */
158struct GNUNET_CURL_Context * 163struct GNUNET_CURL_Context *
159GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, 164GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
160 void *cb_cls)
161{ 165{
162 struct GNUNET_CURL_Context *ctx; 166 struct GNUNET_CURL_Context *ctx;
163 CURLM *multi; 167 CURLM *multi;
@@ -165,8 +169,7 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb,
165 169
166 if (curl_fail) 170 if (curl_fail)
167 { 171 {
168 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 172 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Curl was not initialised properly\n");
169 "Curl was not initialised properly\n");
170 return NULL; 173 return NULL;
171 } 174 }
172 if (NULL == (multi = curl_multi_init ())) 175 if (NULL == (multi = curl_multi_init ()))
@@ -186,9 +189,9 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb,
186 ctx->cb_cls = cb_cls; 189 ctx->cb_cls = cb_cls;
187 ctx->multi = multi; 190 ctx->multi = multi;
188 ctx->share = share; 191 ctx->share = share;
189 GNUNET_assert (NULL != (ctx->json_header = 192 GNUNET_assert (
190 curl_slist_append (NULL, 193 NULL != (ctx->json_header =
191 "Content-Type: application/json"))); 194 curl_slist_append (NULL, "Content-Type: application/json")));
192 return ctx; 195 return ctx;
193} 196}
194 197
@@ -207,10 +210,7 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb,
207 * @return number of bytes processed from @a bufptr 210 * @return number of bytes processed from @a bufptr
208 */ 211 */
209static size_t 212static size_t
210download_cb (char *bufptr, 213download_cb (char *bufptr, size_t size, size_t nitems, void *cls)
211 size_t size,
212 size_t nitems,
213 void *cls)
214{ 214{
215 struct GNUNET_CURL_DownloadBuffer *db = cls; 215 struct GNUNET_CURL_DownloadBuffer *db = cls;
216 size_t msize; 216 size_t msize;
@@ -222,13 +222,12 @@ download_cb (char *bufptr,
222 return 0; 222 return 0;
223 } 223 }
224 msize = size * nitems; 224 msize = size * nitems;
225 if ( (msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED) 225 if ((msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
226 { 226 {
227 db->eno = ENOMEM; 227 db->eno = ENOMEM;
228 return 0; /* signals an error to curl */ 228 return 0; /* signals an error to curl */
229 } 229 }
230 db->buf = GNUNET_realloc (db->buf, 230 db->buf = GNUNET_realloc (db->buf, db->buf_size + msize);
231 db->buf_size + msize);
232 buf = db->buf + db->buf_size; 231 buf = db->buf + db->buf_size;
233 GNUNET_memcpy (buf, bufptr, msize); 232 GNUNET_memcpy (buf, bufptr, msize);
234 db->buf_size += msize; 233 db->buf_size += msize;
@@ -262,10 +261,7 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
262 struct GNUNET_CURL_Job *job; 261 struct GNUNET_CURL_Job *job;
263 262
264 if (GNUNET_YES == add_json) 263 if (GNUNET_YES == add_json)
265 if (CURLE_OK != 264 if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, ctx->json_header))
266 curl_easy_setopt (eh,
267 CURLOPT_HTTPHEADER,
268 ctx->json_header))
269 { 265 {
270 GNUNET_break (0); 266 GNUNET_break (0);
271 curl_easy_cleanup (eh); 267 curl_easy_cleanup (eh);
@@ -273,25 +269,12 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
273 } 269 }
274 270
275 job = GNUNET_new (struct GNUNET_CURL_Job); 271 job = GNUNET_new (struct GNUNET_CURL_Job);
276 if ( (CURLE_OK != 272 if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) ||
277 curl_easy_setopt (eh, 273 (CURLE_OK !=
278 CURLOPT_PRIVATE, 274 curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) ||
279 job)) || 275 (CURLE_OK != curl_easy_setopt (eh, CURLOPT_WRITEDATA, &job->db)) ||
280 (CURLE_OK != 276 (CURLE_OK != curl_easy_setopt (eh, CURLOPT_SHARE, ctx->share)) ||
281 curl_easy_setopt (eh, 277 (CURLM_OK != curl_multi_add_handle (ctx->multi, eh)))
282 CURLOPT_WRITEFUNCTION,
283 &download_cb)) ||
284 (CURLE_OK !=
285 curl_easy_setopt (eh,
286 CURLOPT_WRITEDATA,
287 &job->db)) ||
288 (CURLE_OK !=
289 curl_easy_setopt (eh,
290 CURLOPT_SHARE,
291 ctx->share)) ||
292 (CURLM_OK !=
293 curl_multi_add_handle (ctx->multi,
294 eh)) )
295 { 278 {
296 GNUNET_break (0); 279 GNUNET_break (0);
297 GNUNET_free (job); 280 GNUNET_free (job);
@@ -303,9 +286,7 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
303 job->ctx = ctx; 286 job->ctx = ctx;
304 job->jcc = jcc; 287 job->jcc = jcc;
305 job->jcc_cls = jcc_cls; 288 job->jcc_cls = jcc_cls;
306 GNUNET_CONTAINER_DLL_insert (ctx->jobs_head, 289 GNUNET_CONTAINER_DLL_insert (ctx->jobs_head, ctx->jobs_tail, job);
307 ctx->jobs_tail,
308 job);
309 ctx->cb (ctx->cb_cls); 290 ctx->cb (ctx->cb_cls);
310 return job; 291 return job;
311} 292}
@@ -322,12 +303,9 @@ GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
322{ 303{
323 struct GNUNET_CURL_Context *ctx = job->ctx; 304 struct GNUNET_CURL_Context *ctx = job->ctx;
324 305
325 GNUNET_CONTAINER_DLL_remove (ctx->jobs_head, 306 GNUNET_CONTAINER_DLL_remove (ctx->jobs_head, ctx->jobs_tail, job);
326 ctx->jobs_tail,
327 job);
328 GNUNET_break (CURLM_OK == 307 GNUNET_break (CURLM_OK ==
329 curl_multi_remove_handle (ctx->multi, 308 curl_multi_remove_handle (ctx->multi, job->easy_handle));
330 job->easy_handle));
331 curl_easy_cleanup (job->easy_handle); 309 curl_easy_cleanup (job->easy_handle);
332 GNUNET_free_non_null (job->db.buf); 310 GNUNET_free_non_null (job->db.buf);
333 GNUNET_free (job); 311 GNUNET_free (job);
@@ -366,20 +344,13 @@ download_get_result (struct GNUNET_CURL_DownloadBuffer *db,
366 (int) db->buf_size, 344 (int) db->buf_size,
367 (char *) db->buf); 345 (char *) db->buf);
368 346
369 if ( (CURLE_OK != 347 if ((CURLE_OK != curl_easy_getinfo (eh, CURLINFO_CONTENT_TYPE, &ct)) ||
370 curl_easy_getinfo (eh, 348 (NULL == ct) || (0 != strcasecmp (ct, "application/json")))
371 CURLINFO_CONTENT_TYPE,
372 &ct)) ||
373 (NULL == ct) ||
374 (0 != strcasecmp (ct,
375 "application/json")) )
376 { 349 {
377 /* No content type or explicitly not JSON, refuse to parse 350 /* No content type or explicitly not JSON, refuse to parse
378 (but keep response code) */ 351 (but keep response code) */
379 if (CURLE_OK != 352 if (CURLE_OK !=
380 curl_easy_getinfo (eh, 353 curl_easy_getinfo (eh, CURLINFO_RESPONSE_CODE, response_code))
381 CURLINFO_RESPONSE_CODE,
382 response_code))
383 { 354 {
384 /* unexpected error... */ 355 /* unexpected error... */
385 GNUNET_break (0); 356 GNUNET_break (0);
@@ -409,9 +380,7 @@ download_get_result (struct GNUNET_CURL_DownloadBuffer *db,
409 if (NULL != json) 380 if (NULL != json)
410 { 381 {
411 if (CURLE_OK != 382 if (CURLE_OK !=
412 curl_easy_getinfo (eh, 383 curl_easy_getinfo (eh, CURLINFO_RESPONSE_CODE, response_code))
413 CURLINFO_RESPONSE_CODE,
414 response_code))
415 { 384 {
416 /* unexpected error... */ 385 /* unexpected error... */
417 GNUNET_break (0); 386 GNUNET_break (0);
@@ -430,11 +399,9 @@ download_get_result (struct GNUNET_CURL_DownloadBuffer *db,
430 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. 399 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise.
431 */ 400 */
432int 401int
433GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, 402GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header)
434 const char *header)
435{ 403{
436 ctx->json_header = curl_slist_append (ctx->json_header, 404 ctx->json_header = curl_slist_append (ctx->json_header, header);
437 header);
438 if (NULL == ctx->json_header) 405 if (NULL == ctx->json_header)
439 return GNUNET_SYSERR; 406 return GNUNET_SYSERR;
440 407
@@ -462,96 +429,83 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
462 long response_code; 429 long response_code;
463 void *response; 430 void *response;
464 431
465 (void) curl_multi_perform (ctx->multi, 432 (void) curl_multi_perform (ctx->multi, &n_running);
466 &n_running); 433 while (NULL != (cmsg = curl_multi_info_read (ctx->multi, &n_completed)))
467 while (NULL != (cmsg = curl_multi_info_read (ctx->multi,
468 &n_completed)))
469 { 434 {
470 /* Only documented return value is CURLMSG_DONE */ 435 /* Only documented return value is CURLMSG_DONE */
471 GNUNET_break (CURLMSG_DONE == cmsg->msg); 436 GNUNET_break (CURLMSG_DONE == cmsg->msg);
472 GNUNET_assert (CURLE_OK == 437 GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
473 curl_easy_getinfo (cmsg->easy_handle, 438 CURLINFO_PRIVATE,
474 CURLINFO_PRIVATE, 439 (char **) &job));
475 (char **) &job));
476 GNUNET_assert (job->ctx == ctx); 440 GNUNET_assert (job->ctx == ctx);
477 response_code = 0 ; 441 response_code = 0;
478 response = rp (&job->db, 442 response = rp (&job->db, job->easy_handle, &response_code);
479 job->easy_handle,
480 &response_code);
481#if ENABLE_BENCHMARK 443#if ENABLE_BENCHMARK
482 { 444 {
483 char *url = NULL; 445 char *url = NULL;
484 double total_as_double = 0; 446 double total_as_double = 0;
485 struct GNUNET_TIME_Relative total; 447 struct GNUNET_TIME_Relative total;
486 struct UrlRequestData *urd; 448 struct UrlRequestData *urd;
487 /* Some care required, as curl is using data types (long vs curl_off_t vs 449 /* Some care required, as curl is using data types (long vs curl_off_t vs
488 * double) inconsistently to store byte count. */ 450 * double) inconsistently to store byte count. */
489 curl_off_t size_curl = 0; 451 curl_off_t size_curl = 0;
490 long size_long = 0; 452 long size_long = 0;
491 uint64_t bytes_sent = 0; 453 uint64_t bytes_sent = 0;
492 uint64_t bytes_received = 0; 454 uint64_t bytes_received = 0;
493 455
494 GNUNET_break (CURLE_OK == 456 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
495 curl_easy_getinfo (cmsg->easy_handle, 457 CURLINFO_TOTAL_TIME,
496 CURLINFO_TOTAL_TIME, 458 &total_as_double));
497 &total_as_double)); 459 total.rel_value_us = total_as_double * 1000 * 1000;
498 total.rel_value_us = total_as_double * 1000 * 1000; 460
499 461 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
500 GNUNET_break (CURLE_OK == 462 CURLINFO_EFFECTIVE_URL,
501 curl_easy_getinfo (cmsg->easy_handle, 463 &url));
502 CURLINFO_EFFECTIVE_URL, 464
503 &url)); 465 /* HEADER_SIZE + SIZE_DOWNLOAD_T is hopefully the total
504
505 /* HEADER_SIZE + SIZE_DOWNLOAD_T is hopefully the total
506 number of bytes received, not clear from curl docs. */ 466 number of bytes received, not clear from curl docs. */
507 467
508 GNUNET_break (CURLE_OK == 468 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
509 curl_easy_getinfo (cmsg->easy_handle, 469 CURLINFO_HEADER_SIZE,
510 CURLINFO_HEADER_SIZE, 470 &size_long));
511 &size_long)); 471 bytes_received += size_long;
512 bytes_received += size_long;
513 472
514 GNUNET_break (CURLE_OK == 473 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
515 curl_easy_getinfo (cmsg->easy_handle, 474 CURLINFO_SIZE_DOWNLOAD_T,
516 CURLINFO_SIZE_DOWNLOAD_T, 475 &size_curl));
517 &size_curl)); 476 bytes_received += size_curl;
518 bytes_received += size_curl;
519 477
520 /* REQUEST_SIZE + SIZE_UPLOAD_T is hopefully the total number of bytes 478 /* REQUEST_SIZE + SIZE_UPLOAD_T is hopefully the total number of bytes
521 sent, again docs are not completely clear. */ 479 sent, again docs are not completely clear. */
522 480
523 GNUNET_break (CURLE_OK == 481 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
524 curl_easy_getinfo (cmsg->easy_handle, 482 CURLINFO_REQUEST_SIZE,
525 CURLINFO_REQUEST_SIZE, 483 &size_long));
526 &size_long)); 484 bytes_sent += size_long;
527 bytes_sent += size_long;
528 485
529 /* We obtain this value to check an invariant, but never use it otherwise. */ 486 /* We obtain this value to check an invariant, but never use it otherwise. */
530 GNUNET_break (CURLE_OK == 487 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
531 curl_easy_getinfo (cmsg->easy_handle, 488 CURLINFO_SIZE_UPLOAD_T,
532 CURLINFO_SIZE_UPLOAD_T, 489 &size_curl));
533 &size_curl));
534 490
535 /* CURLINFO_SIZE_UPLOAD_T <= CURLINFO_REQUEST_SIZE should 491 /* CURLINFO_SIZE_UPLOAD_T <= CURLINFO_REQUEST_SIZE should
536 be an invariant. 492 be an invariant.
537 As verified with 493 As verified with
538 curl -w "foo%{size_request} -XPOST --data "ABC" $URL 494 curl -w "foo%{size_request} -XPOST --data "ABC" $URL
539 the CURLINFO_REQUEST_SIZE should be the whole size of the request 495 the CURLINFO_REQUEST_SIZE should be the whole size of the request
540 including headers and body. 496 including headers and body.
541 */ 497 */
542 GNUNET_break (size_curl <= size_long); 498 GNUNET_break (size_curl <= size_long);
543 499
544 urd = get_url_benchmark_data (url, (unsigned int) response_code); 500 urd = get_url_benchmark_data (url, (unsigned int) response_code);
545 urd->count++; 501 urd->count++;
546 urd->time = GNUNET_TIME_relative_add (urd->time, total); 502 urd->time = GNUNET_TIME_relative_add (urd->time, total);
547 urd->time_max = GNUNET_TIME_relative_max (total, urd->time_max); 503 urd->time_max = GNUNET_TIME_relative_max (total, urd->time_max);
548 urd->bytes_sent += bytes_sent; 504 urd->bytes_sent += bytes_sent;
549 urd->bytes_received += bytes_received; 505 urd->bytes_received += bytes_received;
550 } 506 }
551#endif 507#endif
552 job->jcc (job->jcc_cls, 508 job->jcc (job->jcc_cls, response_code, response);
553 response_code,
554 response);
555 rc (response); 509 rc (response);
556 GNUNET_CURL_job_cancel (job); 510 GNUNET_CURL_job_cancel (job);
557 } 511 }
@@ -566,7 +520,7 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
566void 520void
567GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) 521GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
568{ 522{
569 523
570 GNUNET_CURL_perform2 (ctx, 524 GNUNET_CURL_perform2 (ctx,
571 download_get_result, 525 download_get_result,
572 (GNUNET_CURL_ResponseCleaner) &json_decref); 526 (GNUNET_CURL_ResponseCleaner) &json_decref);
@@ -613,25 +567,20 @@ GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx,
613 int m; 567 int m;
614 568
615 m = -1; 569 m = -1;
616 GNUNET_assert (CURLM_OK == 570 GNUNET_assert (CURLM_OK == curl_multi_fdset (ctx->multi,
617 curl_multi_fdset (ctx->multi, 571 read_fd_set,
618 read_fd_set, 572 write_fd_set,
619 write_fd_set, 573 except_fd_set,
620 except_fd_set, 574 &m));
621 &m));
622 to = *timeout; 575 to = *timeout;
623 *max_fd = GNUNET_MAX (m, *max_fd); 576 *max_fd = GNUNET_MAX (m, *max_fd);
624 GNUNET_assert (CURLM_OK == 577 GNUNET_assert (CURLM_OK == curl_multi_timeout (ctx->multi, &to));
625 curl_multi_timeout (ctx->multi,
626 &to));
627 578
628 /* Only if what we got back from curl is smaller than what we 579 /* Only if what we got back from curl is smaller than what we
629 already had (-1 == infinity!), then update timeout */ 580 already had (-1 == infinity!), then update timeout */
630 if ( (to < *timeout) && 581 if ((to < *timeout) && (-1 != to))
631 (-1 != to) )
632 *timeout = to; 582 *timeout = to;
633 if ( (-1 == (*timeout)) && 583 if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
634 (NULL != ctx->jobs_head) )
635 *timeout = to; 584 *timeout = to;
636} 585}
637 586
@@ -658,17 +607,14 @@ GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
658/** 607/**
659 * Initial global setup logic, specifically runs the Curl setup. 608 * Initial global setup logic, specifically runs the Curl setup.
660 */ 609 */
661__attribute__ ((constructor)) 610__attribute__ ((constructor)) void
662void
663GNUNET_CURL_constructor__ (void) 611GNUNET_CURL_constructor__ (void)
664{ 612{
665 CURLcode ret; 613 CURLcode ret;
666 614
667 if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT))) 615 if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT)))
668 { 616 {
669 CURL_STRERROR (GNUNET_ERROR_TYPE_ERROR, 617 CURL_STRERROR (GNUNET_ERROR_TYPE_ERROR, "curl_global_init", ret);
670 "curl_global_init",
671 ret);
672 curl_fail = 1; 618 curl_fail = 1;
673 } 619 }
674} 620}
@@ -677,8 +623,7 @@ GNUNET_CURL_constructor__ (void)
677/** 623/**
678 * Cleans up after us, specifically runs the Curl cleanup. 624 * Cleans up after us, specifically runs the Curl cleanup.
679 */ 625 */
680__attribute__ ((destructor)) 626__attribute__ ((destructor)) void
681void
682GNUNET_CURL_destructor__ (void) 627GNUNET_CURL_destructor__ (void)
683{ 628{
684 if (curl_fail) 629 if (curl_fail)