GNUnet  0.17.6
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 
35 
43 #define CURL_STRERROR(type, function, code) \
44  GNUNET_log (type, \
45  "Curl function `%s' has failed at `%s:%d' with error: %s\n", \
46  function, \
47  __FILE__, \
48  __LINE__, \
49  curl_easy_strerror (code));
50 
54 #define JSON_WARN(error) \
55  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
56  "JSON parsing failed at %s:%u: %s (%s)\n", \
57  __FILE__, \
58  __LINE__, \
59  error.text, \
60  error.source)
61 
62 
67 static int curl_fail;
68 
73 {
78 
83 
87  CURL *easy_handle;
88 
93 
98 
102  void *jcc_cls;
103 
108 
112  void *jcc_raw_cls;
113 
118 
123  struct curl_slist *job_headers;
124 };
125 
126 
131 {
135  CURLM *multi;
136 
140  CURLSH *share;
141 
146 
151 
155  struct curl_slist *common_headers;
156 
162 
168 
172  void *cb_cls;
173 
178  char *userpass;
179 
183  char *certtype;
184 
188  char *certfile;
189 
194  char *keyfile;
195 
199  char *keypass;
200 
201 };
202 
203 
204 void
206  const char *userpass)
207 {
208  GNUNET_free (ctx->userpass);
209  if (NULL != userpass)
210  ctx->userpass = GNUNET_strdup (userpass);
211 }
212 
213 
214 void
216  const char *certtype,
217  const char *certfile,
218  const char *keyfile,
219  const char *keypass)
220 {
221  GNUNET_free (ctx->certtype);
222  GNUNET_free (ctx->certfile);
223  GNUNET_free (ctx->keyfile);
224  GNUNET_free (ctx->keypass);
225  if (NULL != certtype)
226  ctx->certtype = GNUNET_strdup (certtype);
227  if (NULL != certfile)
228  ctx->certfile = GNUNET_strdup (certfile);
229  if (NULL != keyfile)
230  ctx->certtype = GNUNET_strdup (keyfile);
231  if (NULL != keypass)
232  ctx->certtype = GNUNET_strdup (keypass);
233 }
234 
235 
236 struct GNUNET_CURL_Context *
238  void *cb_cls)
239 {
240  struct GNUNET_CURL_Context *ctx;
241  CURLM *multi;
242  CURLSH *share;
243 
244  if (curl_fail)
245  {
247  "Curl was not initialised properly\n");
248  return NULL;
249  }
250  if (NULL == (multi = curl_multi_init ()))
251  {
253  "Failed to create a Curl multi handle\n");
254  return NULL;
255  }
256  if (NULL == (share = curl_share_init ()))
257  {
259  "Failed to create a Curl share handle\n");
260  return NULL;
261  }
263  ctx->cb = cb;
264  ctx->cb_cls = cb_cls;
265  ctx->multi = multi;
266  ctx->share = share;
267  return ctx;
268 }
269 
270 
271 void
273  const char *header_name)
274 {
275  ctx->async_scope_id_header = header_name;
276 }
277 
278 
279 int
280 GNUNET_CURL_is_valid_scope_id (const char *scope_id)
281 {
282  if (strlen (scope_id) >= 64)
283  return GNUNET_NO;
284  for (size_t i = 0; i < strlen (scope_id); i++)
285  if (! (isalnum (scope_id[i]) || (scope_id[i] == '-')))
286  return GNUNET_NO;
287  return GNUNET_YES;
288 }
289 
290 
304 static size_t
305 download_cb (char *bufptr,
306  size_t size,
307  size_t nitems,
308  void *cls)
309 {
310  struct GNUNET_CURL_DownloadBuffer *db = cls;
311  size_t msize;
312  void *buf;
313 
314  if (0 == size * nitems)
315  {
316  /* Nothing (left) to do */
317  return 0;
318  }
319  msize = size * nitems;
320  if ((msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
321  {
322  db->eno = ENOMEM;
323  return 0; /* signals an error to curl */
324  }
325  db->buf = GNUNET_realloc (db->buf,
326  db->buf_size + msize);
327  buf = db->buf + db->buf_size;
328  GNUNET_memcpy (buf, bufptr, msize);
329  db->buf_size += msize;
330  return msize;
331 }
332 
333 
341 static struct curl_slist *
343  const struct curl_slist *job_headers)
344 {
345  struct curl_slist *all_headers = NULL;
346 
347  for (const struct curl_slist *curr = job_headers;
348  NULL != curr;
349  curr = curr->next)
350  {
351  GNUNET_assert (NULL !=
352  (all_headers = curl_slist_append (all_headers,
353  curr->data)));
354  }
355 
356  for (const struct curl_slist *curr = ctx->common_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  if (NULL != ctx->async_scope_id_header)
366  {
368 
370  if (GNUNET_YES == scope.have_scope)
371  {
372  char *aid_header;
373 
374  aid_header =
376  &scope.scope_id,
377  sizeof(struct GNUNET_AsyncScopeId));
378  GNUNET_assert (NULL != aid_header);
379  GNUNET_assert (NULL != curl_slist_append (all_headers,
380  aid_header));
381  GNUNET_free (aid_header);
382  }
383  }
384  return all_headers;
385 }
386 
387 
396 static struct GNUNET_CURL_Job *
397 setup_job (CURL *eh,
398  struct GNUNET_CURL_Context *ctx,
399  struct curl_slist *all_headers)
400 {
401  struct GNUNET_CURL_Job *job;
402 
403  if (CURLE_OK !=
404  curl_easy_setopt (eh,
405  CURLOPT_HTTPHEADER,
406  all_headers))
407  {
408  GNUNET_break (0);
409  curl_slist_free_all (all_headers);
410  curl_easy_cleanup (eh);
411  return NULL;
412  }
413  job = GNUNET_new (struct GNUNET_CURL_Job);
414  job->job_headers = all_headers;
415 
416  if ( (CURLE_OK !=
417  curl_easy_setopt (eh,
418  CURLOPT_PRIVATE,
419  job)) ||
420  (CURLE_OK !=
421  curl_easy_setopt (eh,
422  CURLOPT_WRITEFUNCTION,
423  &download_cb)) ||
424  (CURLE_OK !=
425  curl_easy_setopt (eh,
426  CURLOPT_WRITEDATA,
427  &job->db)) ||
428  (CURLE_OK !=
429  curl_easy_setopt (eh,
430  CURLOPT_SHARE,
431  ctx->share)) )
432  {
433  GNUNET_break (0);
434  GNUNET_free (job);
435  curl_easy_cleanup (eh);
436  return NULL;
437  }
438  if ( (CURLM_OK !=
439  curl_multi_add_handle (ctx->multi,
440  eh)) )
441  {
442  GNUNET_break (0);
443  GNUNET_free (job);
444  curl_easy_cleanup (eh);
445  return NULL;
446  }
447  job->easy_handle = eh;
448  job->ctx = ctx;
449  GNUNET_CONTAINER_DLL_insert (ctx->jobs_head,
450  ctx->jobs_tail,
451  job);
452  return job;
453 }
454 
455 
456 void
458  const struct curl_slist *extra_headers)
459 {
460  struct curl_slist *all_headers = job->job_headers;
461 
462  for (const struct curl_slist *curr = extra_headers;
463  NULL != curr;
464  curr = curr->next)
465  {
466  GNUNET_assert (NULL !=
467  (all_headers = curl_slist_append (all_headers,
468  curr->data)));
469  }
470  job->job_headers = all_headers;
471 }
472 
473 
474 struct GNUNET_CURL_Job *
476  CURL *eh,
477  const struct curl_slist *job_headers,
479  void *jcc_cls)
480 {
481  struct GNUNET_CURL_Job *job;
482  struct curl_slist *all_headers;
483 
484  GNUNET_assert (NULL != jcc);
485  all_headers = setup_job_headers (ctx,
486  job_headers);
487  if (NULL == (job = setup_job (eh,
488  ctx,
489  all_headers)))
490  return NULL;
491  job->jcc_raw = jcc;
492  job->jcc_raw_cls = jcc_cls;
493  ctx->cb (ctx->cb_cls);
494  return job;
495 }
496 
497 
498 struct GNUNET_CURL_Job *
500  CURL *eh,
501  const struct curl_slist *job_headers,
503  void *jcc_cls)
504 {
505  struct GNUNET_CURL_Job *job;
506  struct curl_slist *all_headers;
507 
508  GNUNET_assert (NULL != jcc);
509  if ( (NULL != ctx->userpass) &&
510  (0 != curl_easy_setopt (eh,
511  CURLOPT_USERPWD,
512  ctx->userpass)) )
513  return NULL;
514  if ( (NULL != ctx->certfile) &&
515  (0 != curl_easy_setopt (eh,
516  CURLOPT_SSLCERT,
517  ctx->certfile)) )
518  return NULL;
519  if ( (NULL != ctx->certtype) &&
520  (0 != curl_easy_setopt (eh,
521  CURLOPT_SSLCERTTYPE,
522  ctx->certtype)) )
523  return NULL;
524  if ( (NULL != ctx->keyfile) &&
525  (0 != curl_easy_setopt (eh,
526  CURLOPT_SSLKEY,
527  ctx->keyfile)) )
528  return NULL;
529  if ( (NULL != ctx->keypass) &&
530  (0 != curl_easy_setopt (eh,
531  CURLOPT_KEYPASSWD,
532  ctx->keypass)) )
533  return NULL;
534 
535  all_headers = setup_job_headers (ctx,
536  job_headers);
537  if (NULL == (job = setup_job (eh,
538  ctx,
539  all_headers)))
540  return NULL;
541 
542  job->jcc = jcc;
543  job->jcc_cls = jcc_cls;
544  ctx->cb (ctx->cb_cls);
545  return job;
546 }
547 
548 
549 struct GNUNET_CURL_Job *
551  CURL *eh,
553  void *jcc_cls)
554 {
555  struct GNUNET_CURL_Job *job;
556  struct curl_slist *job_headers = NULL;
557 
558  GNUNET_assert (NULL != (job_headers =
559  curl_slist_append (NULL,
560  "Content-Type: application/json")));
562  eh,
563  job_headers,
564  jcc,
565  jcc_cls);
566  curl_slist_free_all (job_headers);
567  return job;
568 }
569 
570 
571 struct GNUNET_CURL_Job *
573  CURL *eh,
575  void *jcc_cls)
576 {
577  return GNUNET_CURL_job_add2 (ctx,
578  eh,
579  NULL,
580  jcc,
581  jcc_cls);
582 }
583 
584 
585 void
587 {
588  struct GNUNET_CURL_Context *ctx = job->ctx;
589 
590  GNUNET_CONTAINER_DLL_remove (ctx->jobs_head,
591  ctx->jobs_tail,
592  job);
593  GNUNET_break (CURLM_OK ==
594  curl_multi_remove_handle (ctx->multi,
595  job->easy_handle));
596  curl_easy_cleanup (job->easy_handle);
597  GNUNET_free (job->db.buf);
598  curl_slist_free_all (job->job_headers);
599  ctx->cb (ctx->cb_cls);
600  GNUNET_free (job);
601 }
602 
603 
610 static bool
611 is_json (const char *ct)
612 {
613  const char *semi;
614 
615  /* check for "application/json" exact match */
616  if (0 == strcasecmp (ct,
617  "application/json"))
618  return true;
619  /* check for "application/json;[ANYTHING]" */
620  semi = strchr (ct,
621  ';');
622  /* also allow "application/json [ANYTHING]" (note the space!) */
623  if (NULL == semi)
624  semi = strchr (ct,
625  ' ');
626  if (NULL == semi)
627  return false; /* no delimiter we accept, forget it */
628  if (semi - ct != strlen ("application/json"))
629  return false; /* delimiter past desired length, forget it */
630  if (0 == strncasecmp (ct,
631  "application/json",
632  strlen ("application/json")))
633  return true; /* OK */
634  return false;
635 }
636 
637 
638 void *
640  CURL *eh,
641  long *response_code)
642 {
643  json_t *json;
644  json_error_t error;
645  char *ct;
646 
648  "Downloaded body: %.*s\n",
649  (int) db->buf_size,
650  (char *) db->buf);
651  if (CURLE_OK !=
652  curl_easy_getinfo (eh,
653  CURLINFO_RESPONSE_CODE,
654  response_code))
655  {
656  /* unexpected error... */
657  GNUNET_break (0);
658  *response_code = 0;
659  }
660  if ((CURLE_OK !=
661  curl_easy_getinfo (eh,
662  CURLINFO_CONTENT_TYPE,
663  &ct)) ||
664  (NULL == ct) ||
665  (! is_json (ct)))
666  {
667  /* No content type or explicitly not JSON, refuse to parse
668  (but keep response code) */
669  if (0 != db->buf_size)
671  "Did NOT detect response `%.*s' as JSON\n",
672  (int) db->buf_size,
673  (const char *) db->buf);
674  return NULL;
675  }
676  if (MHD_HTTP_NO_CONTENT == *response_code)
677  return NULL;
678  if (0 == *response_code)
679  {
680  char *url;
681 
682  if (CURLE_OK !=
683  curl_easy_getinfo (eh,
684  CURLINFO_EFFECTIVE_URL,
685  &url))
686  url = "<unknown URL>";
688  "Failed to download response from `%s': \n",
689  url);
690  return NULL;
691  }
692  json = NULL;
693  if (0 == db->eno)
694  {
695  json = json_loadb (db->buf,
696  db->buf_size,
697  JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
698  &error);
699  if (NULL == json)
700  {
701  JSON_WARN (error);
702  *response_code = 0;
703  }
704  }
705  GNUNET_free (db->buf);
706  db->buf = NULL;
707  db->buf_size = 0;
708  return json;
709 }
710 
711 
714  const char *header)
715 {
716  ctx->common_headers = curl_slist_append (ctx->common_headers,
717  header);
718  if (NULL == ctx->common_headers)
719  return GNUNET_SYSERR;
720 
721  return GNUNET_OK;
722 }
723 
724 
725 void
729 {
730  CURLMsg *cmsg;
731  int n_running;
732  int n_completed;
733 
734  (void) curl_multi_perform (ctx->multi,
735  &n_running);
736  while (NULL != (cmsg = curl_multi_info_read (ctx->multi,
737  &n_completed)))
738  {
739  struct GNUNET_CURL_Job *job;
740  long response_code;
741  void *response;
742 
743  /* Only documented return value is CURLMSG_DONE */
744  GNUNET_break (CURLMSG_DONE == cmsg->msg);
745  GNUNET_assert (CURLE_OK ==
746  curl_easy_getinfo (cmsg->easy_handle,
747  CURLINFO_PRIVATE,
748  (char **) &job));
749  GNUNET_assert (job->ctx == ctx);
750  response_code = 0;
751  if (NULL != job->jcc_raw)
752  {
753  /* RAW mode, no parsing */
754  GNUNET_break (CURLE_OK ==
755  curl_easy_getinfo (job->easy_handle,
756  CURLINFO_RESPONSE_CODE,
757  &response_code));
758  job->jcc_raw (job->jcc_raw_cls,
759  response_code,
760  job->db.buf,
761  job->db.buf_size);
762  }
763  else
764  {
765  /* to be parsed via 'rp' */
766  response = rp (&job->db,
767  job->easy_handle,
768  &response_code);
769  job->jcc (job->jcc_cls,
770  response_code,
771  response);
772  rc (response);
773  }
775  }
776 }
777 
778 
779 void
781 {
784  (GNUNET_CURL_ResponseCleaner) & json_decref);
785 }
786 
787 
788 void
790  fd_set *read_fd_set,
791  fd_set *write_fd_set,
792  fd_set *except_fd_set,
793  int *max_fd,
794  long *timeout)
795 {
796  long to;
797  int m;
798 
799  m = -1;
800  GNUNET_assert (CURLM_OK ==
801  curl_multi_fdset (ctx->multi,
802  read_fd_set,
803  write_fd_set,
804  except_fd_set,
805  &m));
806  to = *timeout;
807  *max_fd = GNUNET_MAX (m, *max_fd);
808  GNUNET_assert (CURLM_OK ==
809  curl_multi_timeout (ctx->multi,
810  &to));
811 
812  /* Only if what we got back from curl is smaller than what we
813  already had (-1 == infinity!), then update timeout */
814  if ((to < *timeout) && (-1 != to))
815  *timeout = to;
816  if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
817  *timeout = to;
818 }
819 
820 
821 void
823 {
824  /* all jobs must have been cancelled at this time, assert this */
825  GNUNET_assert (NULL == ctx->jobs_head);
826  curl_share_cleanup (ctx->share);
827  curl_multi_cleanup (ctx->multi);
828  curl_slist_free_all (ctx->common_headers);
829  GNUNET_free (ctx->userpass);
830  GNUNET_free (ctx->certtype);
831  GNUNET_free (ctx->certfile);
832  GNUNET_free (ctx->keyfile);
833  GNUNET_free (ctx->keypass);
834  GNUNET_free (ctx);
835 }
836 
837 
841 __attribute__ ((constructor)) void
842 GNUNET_CURL_constructor__ (void)
843 {
844  CURLcode ret;
845 
846  if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT)))
847  {
849  "curl_global_init",
850  ret);
851  curl_fail = 1;
852  }
853 }
854 
855 
859 __attribute__ ((destructor)) void
860 GNUNET_CURL_destructor__ (void)
861 {
862  if (curl_fail)
863  return;
864  curl_global_cleanup ();
865 }
866 
867 
868 /* end of curl.c */
__attribute__((constructor))
Initial global setup logic, specifically runs the Curl setup.
Definition: curl.c:841
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:342
#define CURL_STRERROR(type, function, code)
Log error related to CURL operations.
Definition: curl.c:43
static bool is_json(const char *ct)
Test if the given content type ct is JSON.
Definition: curl.c:611
#define JSON_WARN(error)
Print JSON parsing related error information.
Definition: curl.c:54
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:305
static int curl_fail
Failsafe flag.
Definition: curl.c:67
void * GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Definition: curl.c:639
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:397
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
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 char * rp
Relying party.
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:94
static char buf[2048]
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
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:215
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.
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:789
void GNUNET_CURL_fini(struct GNUNET_CURL_Context *ctx)
Cleanup library initialisation resources.
Definition: curl.c:822
void(* GNUNET_CURL_ResponseCleaner)(void *response)
Deallocate the response.
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:499
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:457
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:572
struct GNUNET_CURL_Context * GNUNET_CURL_init(GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
Initialise this library.
Definition: curl.c:237
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:726
void GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
Cancel a job.
Definition: curl.c:586
void GNUNET_CURL_perform(struct GNUNET_CURL_Context *ctx)
Run the main event loop for the CURL interaction.
Definition: curl.c:780
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:550
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:205
int 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:280
void *(* GNUNET_CURL_RawParser)(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Parses the raw response we got from the Web server.
enum GNUNET_GenericReturnValue GNUNET_CURL_append_header(struct GNUNET_CURL_Context *ctx, const char *header)
Add custom request header.
Definition: curl.c:713
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...
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:475
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:272
#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.
Definition: gnunet_common.h:96
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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
#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
static unsigned int size
Size of the "table".
Definition: peer.c:67
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
Identifier for an asynchronous execution context.
Saved async scope identifier or root scope.
Context.
Definition: curl.c:131
char * userpass
USERNAME:PASSWORD to use for client-authentication with all requests of this context,...
Definition: curl.c:178
char * keypass
Passphrase to decrypt keyfile, or NULL.
Definition: curl.c:199
void * cb_cls
Closure for cb.
Definition: curl.c:172
char * certtype
Type of the TLS client certificate used, or NULL.
Definition: curl.c:183
char * keyfile
File with the private key to authenticate the TLS client, or NULL.
Definition: curl.c:194
struct curl_slist * common_headers
Headers common for all requests in the context.
Definition: curl.c:155
CURLSH * share
Curl share handle.
Definition: curl.c:140
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:161
CURLM * multi
Curl multi handle.
Definition: curl.c:135
GNUNET_CURL_RescheduleCallback cb
Function we need to call whenever the event loop's socket set changed.
Definition: curl.c:167
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:145
char * certfile
File with the TLS client certificate, or NULL.
Definition: curl.c:188
struct GNUNET_CURL_Job * jobs_tail
We keep jobs in a DLL.
Definition: curl.c:150
Buffer data structure we use to buffer the HTTP download before giving it to the JSON parser.
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition: curl.c:73
struct GNUNET_CURL_Job * prev
We keep jobs in a DLL.
Definition: curl.c:82
CURL * easy_handle
Easy handle of the job.
Definition: curl.c:87
struct curl_slist * job_headers
Headers used for this job, the list needs to be freed after the job has finished.
Definition: curl.c:123
void * jcc_raw_cls
Closure for jcc_raw.
Definition: curl.c:112
struct GNUNET_CURL_Context * ctx
Context this job runs in.
Definition: curl.c:92
GNUNET_CURL_JobCompletionCallback jcc
Function to call upon completion.
Definition: curl.c:97
void * jcc_cls
Closure for jcc.
Definition: curl.c:102
struct GNUNET_CURL_DownloadBuffer db
Buffer for response received from CURL.
Definition: curl.c:117
struct GNUNET_CURL_Job * next
We keep jobs in a DLL.
Definition: curl.c:77
GNUNET_CURL_RawJobCompletionCallback jcc_raw
Function to call upon completion.
Definition: curl.c:107