GNUnet 0.21.1
curl.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
26#include "platform.h"
27#include <jansson.h>
28#include <microhttpd.h>
29#include "gnunet_curl_lib.h"
30
31#if ENABLE_BENCHMARK
32#include "../util/benchmark.h"
33#endif
34
38#define DEBUG 0
39
47#define CURL_STRERROR(type, function, code) \
48 GNUNET_log (type, \
49 "Curl function `%s' has failed at `%s:%d' with error: %s\n", \
50 function, \
51 __FILE__, \
52 __LINE__, \
53 curl_easy_strerror (code));
54
58#define JSON_WARN(error) \
59 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
60 "JSON parsing failed at %s:%u: %s (%s)\n", \
61 __FILE__, \
62 __LINE__, \
63 error.text, \
64 error.source)
65
66
71static int curl_fail;
72
77{
82
87
92
97
102
106 void *jcc_cls;
107
112
117
122
127 struct curl_slist *job_headers;
128
133};
134
135
140{
144 CURLM *multi;
145
149 CURLSH *share;
150
155
160
164 struct curl_slist *common_headers;
165
171
177
181 void *cb_cls;
182
187 char *userpass;
188
192 char *certtype;
193
197 char *certfile;
198
203 char *keyfile;
204
208 char *keypass;
209
210};
211
212
213void
215 const char *userpass)
216{
217 GNUNET_free (ctx->userpass);
218 if (NULL != userpass)
219 ctx->userpass = GNUNET_strdup (userpass);
220}
221
222
223void
225 const char *certtype,
226 const char *certfile,
227 const char *keyfile,
228 const char *keypass)
229{
230 GNUNET_free (ctx->certtype);
231 GNUNET_free (ctx->certfile);
232 GNUNET_free (ctx->keyfile);
233 GNUNET_free (ctx->keypass);
234 if (NULL != certtype)
235 ctx->certtype = GNUNET_strdup (certtype);
236 if (NULL != certfile)
237 ctx->certfile = GNUNET_strdup (certfile);
238 if (NULL != keyfile)
239 ctx->certtype = GNUNET_strdup (keyfile);
240 if (NULL != keypass)
241 ctx->certtype = GNUNET_strdup (keypass);
242}
243
244
245struct GNUNET_CURL_Context *
247 void *cb_cls)
248{
249 struct GNUNET_CURL_Context *ctx;
250 CURLM *multi;
251 CURLSH *share;
252
253 if (curl_fail)
254 {
256 "Curl was not initialised properly\n");
257 return NULL;
258 }
259 if (NULL == (multi = curl_multi_init ()))
260 {
262 "Failed to create a Curl multi handle\n");
263 return NULL;
264 }
265 if (NULL == (share = curl_share_init ()))
266 {
268 "Failed to create a Curl share handle\n");
269 return NULL;
270 }
272 ctx->cb = cb;
273 ctx->cb_cls = cb_cls;
274 ctx->multi = multi;
275 ctx->share = share;
276 return ctx;
277}
278
279
280void
282 const char *header_name)
283{
284 ctx->async_scope_id_header = header_name;
285}
286
287
289GNUNET_CURL_is_valid_scope_id (const char *scope_id)
290{
291 if (strlen (scope_id) >= 64)
292 return GNUNET_NO;
293 for (size_t i = 0; i < strlen (scope_id); i++)
294 if (! (isalnum (scope_id[i]) || (scope_id[i] == '-')))
295 return GNUNET_NO;
296 return GNUNET_YES;
297}
298
299
313static size_t
314download_cb (char *bufptr,
315 size_t size,
316 size_t nitems,
317 void *cls)
318{
319 struct GNUNET_CURL_DownloadBuffer *db = cls;
320 size_t msize;
321 void *buf;
322
323 if (0 == size * nitems)
324 {
325 /* Nothing (left) to do */
326 return 0;
327 }
328 msize = size * nitems;
329 if ((msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
330 {
331 db->eno = ENOMEM;
332 return 0; /* signals an error to curl */
333 }
334 db->buf = GNUNET_realloc (db->buf,
335 db->buf_size + msize);
336 buf = db->buf + db->buf_size;
337 GNUNET_memcpy (buf, bufptr, msize);
338 db->buf_size += msize;
339 return msize;
340}
341
342
350static struct curl_slist *
352 const struct curl_slist *job_headers)
353{
354 struct curl_slist *all_headers = NULL;
355
356 for (const struct curl_slist *curr = job_headers;
357 NULL != curr;
358 curr = curr->next)
359 {
360 GNUNET_assert (NULL !=
361 (all_headers = curl_slist_append (all_headers,
362 curr->data)));
363 }
364
365 for (const struct curl_slist *curr = ctx->common_headers;
366 NULL != curr;
367 curr = curr->next)
368 {
369 GNUNET_assert (NULL !=
370 (all_headers = curl_slist_append (all_headers,
371 curr->data)));
372 }
373
374 if (NULL != ctx->async_scope_id_header)
375 {
376 struct GNUNET_AsyncScopeSave scope;
377
378 GNUNET_async_scope_get (&scope);
379 if (GNUNET_YES == scope.have_scope)
380 {
381 char *aid_header;
382
383 aid_header =
385 &scope.scope_id,
386 sizeof(struct GNUNET_AsyncScopeId));
387 GNUNET_assert (NULL != aid_header);
388 GNUNET_assert (NULL != curl_slist_append (all_headers,
389 aid_header));
390 GNUNET_free (aid_header);
391 }
392 }
393 return all_headers;
394}
395
396
405static struct GNUNET_CURL_Job *
406setup_job (CURL *eh,
407 struct GNUNET_CURL_Context *ctx,
408 struct curl_slist *all_headers)
409{
410 struct GNUNET_CURL_Job *job;
411
412 if (CURLE_OK !=
413 curl_easy_setopt (eh,
414 CURLOPT_HTTPHEADER,
415 all_headers))
416 {
417 GNUNET_break (0);
418 curl_slist_free_all (all_headers);
419 curl_easy_cleanup (eh);
420 return NULL;
421 }
422 job = GNUNET_new (struct GNUNET_CURL_Job);
423 job->start_time = GNUNET_TIME_absolute_get ();
424 job->job_headers = all_headers;
425
426 if ( (CURLE_OK !=
427 curl_easy_setopt (eh,
428 CURLOPT_PRIVATE,
429 job)) ||
430 (CURLE_OK !=
431 curl_easy_setopt (eh,
432 CURLOPT_WRITEFUNCTION,
433 &download_cb)) ||
434 (CURLE_OK !=
435 curl_easy_setopt (eh,
436 CURLOPT_WRITEDATA,
437 &job->db)) ||
438 (CURLE_OK !=
439 curl_easy_setopt (eh,
440 CURLOPT_SHARE,
441 ctx->share)) )
442 {
443 GNUNET_break (0);
445 curl_easy_cleanup (eh);
446 return NULL;
447 }
448 if ( (CURLM_OK !=
449 curl_multi_add_handle (ctx->multi,
450 eh)) )
451 {
452 GNUNET_break (0);
454 curl_easy_cleanup (eh);
455 return NULL;
456 }
457 job->easy_handle = eh;
458 job->ctx = ctx;
460 ctx->jobs_tail,
461 job);
462 return job;
463}
464
465
466void
468 const struct curl_slist *extra_headers)
469{
470 struct curl_slist *all_headers = job->job_headers;
471
472 for (const struct curl_slist *curr = extra_headers;
473 NULL != curr;
474 curr = curr->next)
475 {
476 GNUNET_assert (NULL !=
477 (all_headers = curl_slist_append (all_headers,
478 curr->data)));
479 }
480 job->job_headers = all_headers;
481}
482
483
484struct GNUNET_CURL_Job *
486 CURL *eh,
487 const struct curl_slist *job_headers,
489 void *jcc_cls)
490{
491 struct GNUNET_CURL_Job *job;
492 struct curl_slist *all_headers;
493
494 GNUNET_assert (NULL != jcc);
495 all_headers = setup_job_headers (ctx,
496 job_headers);
497 if (NULL == (job = setup_job (eh,
498 ctx,
499 all_headers)))
500 return NULL;
501 job->jcc_raw = jcc;
502 job->jcc_raw_cls = jcc_cls;
503 ctx->cb (ctx->cb_cls);
504 return job;
505}
506
507
508struct GNUNET_CURL_Job *
510 CURL *eh,
511 const struct curl_slist *job_headers,
513 void *jcc_cls)
514{
515 struct GNUNET_CURL_Job *job;
516 struct curl_slist *all_headers;
517
518 GNUNET_assert (NULL != jcc);
519 if ( (NULL != ctx->userpass) &&
520 (0 != curl_easy_setopt (eh,
521 CURLOPT_USERPWD,
522 ctx->userpass)) )
523 return NULL;
524 if ( (NULL != ctx->certfile) &&
525 (0 != curl_easy_setopt (eh,
526 CURLOPT_SSLCERT,
527 ctx->certfile)) )
528 return NULL;
529 if ( (NULL != ctx->certtype) &&
530 (0 != curl_easy_setopt (eh,
531 CURLOPT_SSLCERTTYPE,
532 ctx->certtype)) )
533 return NULL;
534 if ( (NULL != ctx->keyfile) &&
535 (0 != curl_easy_setopt (eh,
536 CURLOPT_SSLKEY,
537 ctx->keyfile)) )
538 return NULL;
539 if ( (NULL != ctx->keypass) &&
540 (0 != curl_easy_setopt (eh,
541 CURLOPT_KEYPASSWD,
542 ctx->keypass)) )
543 return NULL;
544
545 all_headers = setup_job_headers (ctx,
546 job_headers);
547 if (NULL == (job = setup_job (eh,
548 ctx,
549 all_headers)))
550 return NULL;
551
552 job->jcc = jcc;
553 job->jcc_cls = jcc_cls;
554 ctx->cb (ctx->cb_cls);
555 return job;
556}
557
558
559struct GNUNET_CURL_Job *
561 CURL *eh,
563 void *jcc_cls)
564{
565 struct GNUNET_CURL_Job *job;
566 struct curl_slist *job_headers = NULL;
567
568 GNUNET_assert (NULL != (job_headers =
569 curl_slist_append (NULL,
570 "Content-Type: application/json")));
572 eh,
573 job_headers,
574 jcc,
575 jcc_cls);
576 curl_slist_free_all (job_headers);
577 return job;
578}
579
580
581struct GNUNET_CURL_Job *
583 CURL *eh,
585 void *jcc_cls)
586{
588 eh,
589 NULL,
590 jcc,
591 jcc_cls);
592}
593
594
595void
597{
598 struct GNUNET_CURL_Context *ctx = job->ctx;
599
601 ctx->jobs_tail,
602 job);
603 GNUNET_break (CURLM_OK ==
604 curl_multi_remove_handle (ctx->multi,
605 job->easy_handle));
606 curl_easy_cleanup (job->easy_handle);
607 GNUNET_free (job->db.buf);
608 curl_slist_free_all (job->job_headers);
609 ctx->cb (ctx->cb_cls);
611}
612
613
620static bool
621is_json (const char *ct)
622{
623 const char *semi;
624
625 /* check for "application/json" exact match */
626 if (0 == strcasecmp (ct,
627 "application/json"))
628 return true;
629 /* check for "application/json;[ANYTHING]" */
630 semi = strchr (ct,
631 ';');
632 /* also allow "application/json [ANYTHING]" (note the space!) */
633 if (NULL == semi)
634 semi = strchr (ct,
635 ' ');
636 if (NULL == semi)
637 return false; /* no delimiter we accept, forget it */
638 if (semi - ct != strlen ("application/json"))
639 return false; /* delimiter past desired length, forget it */
640 if (0 == strncasecmp (ct,
641 "application/json",
642 strlen ("application/json")))
643 return true; /* OK */
644 return false;
645}
646
647
648void *
650 CURL *eh,
651 long *response_code)
652{
653 json_t *json;
654 json_error_t error;
655 char *ct;
656
657#if DEBUG
659 "Downloaded body: %.*s\n",
660 (int) db->buf_size,
661 (char *) db->buf);
662#endif
663 if (CURLE_OK !=
664 curl_easy_getinfo (eh,
665 CURLINFO_RESPONSE_CODE,
666 response_code))
667 {
668 /* unexpected error... */
669 GNUNET_break (0);
670 *response_code = 0;
671 }
672 if (MHD_HTTP_NO_CONTENT == *response_code)
673 return NULL;
674 if ((CURLE_OK !=
675 curl_easy_getinfo (eh,
676 CURLINFO_CONTENT_TYPE,
677 &ct)) ||
678 (NULL == ct) ||
679 (! is_json (ct)))
680 {
681 /* No content type or explicitly not JSON, refuse to parse
682 (but keep response code) */
683 if (0 != db->buf_size)
684 {
685 char *url;
686
687 if (CURLE_OK !=
688 curl_easy_getinfo (eh,
689 CURLINFO_EFFECTIVE_URL,
690 &url))
691 url = "<unknown URL>";
693 "Request to `%s' was expected to return a body of type `application/json', got `%s'\n",
694 url,
695 ct);
696 }
697 return NULL;
698 }
699 if (0 == *response_code)
700 {
701 char *url;
702
703 if (CURLE_OK !=
704 curl_easy_getinfo (eh,
705 CURLINFO_EFFECTIVE_URL,
706 &url))
707 url = "<unknown URL>";
709 "Failed to download response from `%s': \n",
710 url);
711 return NULL;
712 }
713 json = NULL;
714 if (0 == db->eno)
715 {
716 json = json_loadb (db->buf,
717 db->buf_size,
718 JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
719 &error);
720 if (NULL == json)
721 {
722 JSON_WARN (error);
723 *response_code = 0;
724 }
725 }
726 GNUNET_free (db->buf);
727 db->buf = NULL;
728 db->buf_size = 0;
729 return json;
730}
731
732
735 const char *header)
736{
737 ctx->common_headers = curl_slist_append (ctx->common_headers,
738 header);
739 if (NULL == ctx->common_headers)
740 return GNUNET_SYSERR;
741
742 return GNUNET_OK;
743}
744
745
746void
750{
751 CURLMsg *cmsg;
752 int n_running;
753 int n_completed;
754
755 (void) curl_multi_perform (ctx->multi,
756 &n_running);
757 while (NULL != (cmsg = curl_multi_info_read (ctx->multi,
758 &n_completed)))
759 {
760 struct GNUNET_CURL_Job *job;
762 long response_code;
763 void *response;
764
765 /* Only documented return value is CURLMSG_DONE */
766 GNUNET_break (CURLMSG_DONE == cmsg->msg);
767 GNUNET_assert (CURLE_OK ==
768 curl_easy_getinfo (cmsg->easy_handle,
769 CURLINFO_PRIVATE,
770 (char **) &job));
771 GNUNET_assert (job->ctx == ctx);
772 response_code = 0;
774 if (NULL != job->jcc_raw)
775 {
776 /* RAW mode, no parsing */
777 GNUNET_break (CURLE_OK ==
778 curl_easy_getinfo (job->easy_handle,
779 CURLINFO_RESPONSE_CODE,
780 &response_code));
781 job->jcc_raw (job->jcc_raw_cls,
782 response_code,
783 job->db.buf,
784 job->db.buf_size);
785 }
786 else
787 {
788 /* to be parsed via 'rp' */
789 response = rp (&job->db,
790 job->easy_handle,
791 &response_code);
792 job->jcc (job->jcc_cls,
793 response_code,
794 response);
795 rc (response);
796 }
797 {
798 char *url = NULL;
799
800 if (CURLE_UNKNOWN_OPTION ==
801 curl_easy_getinfo (job->easy_handle,
802 CURLINFO_EFFECTIVE_URL,
803 &url))
804 url = "<unknown>";
806 "HTTP request for `%s' finished with %u after %s\n",
807 url,
808 (unsigned int) response_code,
810 true));
811 /* Note: we MUST NOT free 'url' here */
812 }
814 }
815}
816
817
818void
820{
823 (GNUNET_CURL_ResponseCleaner) & json_decref);
824}
825
826
827void
829 fd_set *read_fd_set,
830 fd_set *write_fd_set,
831 fd_set *except_fd_set,
832 int *max_fd,
833 long *timeout)
834{
835 long to;
836 int m;
837
838 m = -1;
839 GNUNET_assert (CURLM_OK ==
840 curl_multi_fdset (ctx->multi,
841 read_fd_set,
842 write_fd_set,
843 except_fd_set,
844 &m));
845 to = *timeout;
846 *max_fd = GNUNET_MAX (m, *max_fd);
847 GNUNET_assert (CURLM_OK ==
848 curl_multi_timeout (ctx->multi,
849 &to));
850
851 /* Only if what we got back from curl is smaller than what we
852 already had (-1 == infinity!), then update timeout */
853 if ((to < *timeout) && (-1 != to))
854 *timeout = to;
855 if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
856 *timeout = to;
857}
858
859
860void
862{
863 /* all jobs must have been cancelled at this time, assert this */
864 GNUNET_assert (NULL == ctx->jobs_head);
865 curl_share_cleanup (ctx->share);
866 curl_multi_cleanup (ctx->multi);
867 curl_slist_free_all (ctx->common_headers);
868 GNUNET_free (ctx->userpass);
869 GNUNET_free (ctx->certtype);
870 GNUNET_free (ctx->certfile);
871 GNUNET_free (ctx->keyfile);
872 GNUNET_free (ctx->keypass);
874}
875
876
880__attribute__ ((constructor)) void
881GNUNET_CURL_constructor__ (void)
882{
883 CURLcode ret;
884
885 if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT)))
886 {
888 "curl_global_init",
889 ret);
890 curl_fail = 1;
891 }
892}
893
894
898__attribute__ ((destructor)) void
899GNUNET_CURL_destructor__ (void)
900{
901 if (curl_fail)
902 return;
903 curl_global_cleanup ();
904}
905
906
907/* end of curl.c */
__attribute__((constructor))
Initial global setup logic, specifically runs the Curl setup.
Definition: curl.c:880
#define CURL_STRERROR(type, function, code)
Log error related to CURL operations.
Definition: curl.c:47
static bool is_json(const char *ct)
Test if the given content type ct is JSON.
Definition: curl.c:621
#define JSON_WARN(error)
Print JSON parsing related error information.
Definition: curl.c:58
static struct GNUNET_CURL_Job * setup_job(CURL *eh, struct GNUNET_CURL_Context *ctx, struct curl_slist *all_headers)
Create a job.
Definition: curl.c:406
static size_t download_cb(char *bufptr, size_t size, size_t nitems, void *cls)
Callback used when downloading the reply to an HTTP request.
Definition: curl.c:314
static int curl_fail
Failsafe flag.
Definition: curl.c:71
static struct curl_slist * setup_job_headers(struct GNUNET_CURL_Context *ctx, const struct curl_slist *job_headers)
Create the HTTP headers for the request.
Definition: curl.c:351
void * GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Definition: curl.c:649
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:119
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
Definition: gnunet-cadet.c:137
static CURLM * multi
Current multi-CURL handle.
static struct MHD_Response * response
Our canonical response.
static struct GNUNET_FS_Handle * ctx
static char * rp
Relying party.
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:97
static struct GNUNET_TIME_Relative duration
Option '-d': duration of the mapping.
Definition: gnunet-vpn.c:90
library to make it easy to download JSON replies over HTTP
void GNUNET_CURL_set_tlscert(struct GNUNET_CURL_Context *ctx, const char *certtype, const char *certfile, const char *keyfile, const char *keypass)
Force use of the provided TLS client certificate for client authentication for all operations perform...
Definition: curl.c:224
void(* GNUNET_CURL_RawJobCompletionCallback)(void *cls, long response_code, const void *body, size_t body_size)
Function to call upon completion of a raw job.
void(* GNUNET_CURL_JobCompletionCallback)(void *cls, long response_code, const void *response)
Function to call upon completion of a job.
struct GNUNET_CURL_Job * GNUNET_CURL_job_add_raw(struct GNUNET_CURL_Context *ctx, CURL *eh, const struct curl_slist *job_headers, GNUNET_CURL_RawJobCompletionCallback jcc, void *jcc_cls)
Schedule a CURL request to be executed and call the given jcc upon its completion.
Definition: curl.c:485
struct GNUNET_CURL_Job * GNUNET_CURL_job_add(struct GNUNET_CURL_Context *ctx, CURL *eh, GNUNET_CURL_JobCompletionCallback jcc, void *jcc_cls)
Schedule a CURL request to be executed and call the given jcc upon its completion.
Definition: curl.c:582
void GNUNET_CURL_get_select_info(struct GNUNET_CURL_Context *ctx, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, int *max_fd, long *timeout)
Obtain the information for a select() call to wait until GNUNET_CURL_perform() is ready again.
Definition: curl.c:828
struct GNUNET_CURL_Context * GNUNET_CURL_init(GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
Initialise this library.
Definition: curl.c:246
void GNUNET_CURL_fini(struct GNUNET_CURL_Context *ctx)
Cleanup library initialisation resources.
Definition: curl.c:861
void(* GNUNET_CURL_ResponseCleaner)(void *response)
Deallocate the response.
void GNUNET_CURL_extend_headers(struct GNUNET_CURL_Job *job, const struct curl_slist *extra_headers)
Add extra_headers to the HTTP headers for job.
Definition: curl.c:467
void GNUNET_CURL_perform2(struct GNUNET_CURL_Context *ctx, GNUNET_CURL_RawParser rp, GNUNET_CURL_ResponseCleaner rc)
Run the main event loop for the HTTP interaction.
Definition: curl.c:747
void GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
Cancel a job.
Definition: curl.c:596
enum GNUNET_GenericReturnValue GNUNET_CURL_is_valid_scope_id(const char *scope_id)
Return GNUNET_YES if given a valid scope ID and GNUNET_NO otherwise.
Definition: curl.c:289
void GNUNET_CURL_perform(struct GNUNET_CURL_Context *ctx)
Run the main event loop for the CURL interaction.
Definition: curl.c:819
void GNUNET_CURL_set_userpass(struct GNUNET_CURL_Context *ctx, const char *userpass)
Force use of the provided username and password for client authentication for all operations performe...
Definition: curl.c:214
void *(* GNUNET_CURL_RawParser)(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Parses the raw response we got from the Web server.
struct GNUNET_CURL_Job * GNUNET_CURL_job_add_with_ct_json(struct GNUNET_CURL_Context *ctx, CURL *eh, GNUNET_CURL_JobCompletionCallback jcc, void *jcc_cls)
Schedule a CURL request to be executed and call the given jcc upon its completion.
Definition: curl.c:560
enum GNUNET_GenericReturnValue GNUNET_CURL_append_header(struct GNUNET_CURL_Context *ctx, const char *header)
Add custom request header.
Definition: curl.c:734
void(* GNUNET_CURL_RescheduleCallback)(void *cls)
Function called by the context to ask for the event loop to be rescheduled, that is the application s...
void GNUNET_CURL_enable_async_scope_header(struct GNUNET_CURL_Context *ctx, const char *header_name)
Enable sending the async scope ID as a header.
Definition: curl.c:281
struct GNUNET_CURL_Job * GNUNET_CURL_job_add2(struct GNUNET_CURL_Context *ctx, CURL *eh, const struct curl_slist *job_headers, GNUNET_CURL_JobCompletionCallback jcc, void *jcc_cls)
Schedule a CURL request to be executed and call the given jcc upon its completion.
Definition: curl.c:509
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:764
const char * GNUNET_TIME_relative2s(struct GNUNET_TIME_Relative delta, bool do_round)
Give relative time in human-readable fancy format.
Definition: time.c:264
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:436
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
@ MHD_HTTP_NO_CONTENT
No Content [RFC7231, Section 6.3.5].
static unsigned int size
Size of the "table".
Definition: peer.c:68
Identifier for an asynchronous execution context.
Saved async scope identifier or root scope.
int have_scope
GNUNET_YES unless this saved scope is the unnamed root scope.
struct GNUNET_AsyncScopeId scope_id
Saved scope.
Context.
Definition: curl.c:140
char * userpass
USERNAME:PASSWORD to use for client-authentication with all requests of this context,...
Definition: curl.c:187
char * keypass
Passphrase to decrypt keyfile, or NULL.
Definition: curl.c:208
void * cb_cls
Closure for cb.
Definition: curl.c:181
char * certtype
Type of the TLS client certificate used, or NULL.
Definition: curl.c:192
char * keyfile
File with the private key to authenticate the TLS client, or NULL.
Definition: curl.c:203
struct curl_slist * common_headers
Headers common for all requests in the context.
Definition: curl.c:164
CURLSH * share
Curl share handle.
Definition: curl.c:149
const char * async_scope_id_header
If non-NULL, the async scope ID is sent in a request header of this name.
Definition: curl.c:170
CURLM * multi
Curl multi handle.
Definition: curl.c:144
GNUNET_CURL_RescheduleCallback cb
Function we need to call whenever the event loop's socket set changed.
Definition: curl.c:176
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:154
char * certfile
File with the TLS client certificate, or NULL.
Definition: curl.c:197
struct GNUNET_CURL_Job * jobs_tail
We keep jobs in a DLL.
Definition: curl.c:159
Buffer data structure we use to buffer the HTTP download before giving it to the JSON parser.
void * buf
Download buffer.
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition: curl.c:77
struct GNUNET_CURL_Job * prev
We keep jobs in a DLL.
Definition: curl.c:86
CURL * easy_handle
Easy handle of the job.
Definition: curl.c:91
struct curl_slist * job_headers
Headers used for this job, the list needs to be freed after the job has finished.
Definition: curl.c:127
void * jcc_raw_cls
Closure for jcc_raw.
Definition: curl.c:116
struct GNUNET_CURL_Context * ctx
Context this job runs in.
Definition: curl.c:96
struct GNUNET_TIME_Absolute start_time
When did we start the job?
Definition: curl.c:132
GNUNET_CURL_JobCompletionCallback jcc
Function to call upon completion.
Definition: curl.c:101
void * jcc_cls
Closure for jcc.
Definition: curl.c:106
struct GNUNET_CURL_DownloadBuffer db
Buffer for response received from CURL.
Definition: curl.c:121
struct GNUNET_CURL_Job * next
We keep jobs in a DLL.
Definition: curl.c:81
GNUNET_CURL_RawJobCompletionCallback jcc_raw
Function to call upon completion.
Definition: curl.c:111
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.