GNUnet  0.11.x
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  (CURLM_OK !=
433  curl_multi_add_handle (ctx->multi,
434  eh)) )
435  {
436  GNUNET_break (0);
437  GNUNET_free (job);
438  curl_easy_cleanup (eh);
439  return NULL;
440  }
441  job->easy_handle = eh;
442  job->ctx = ctx;
443  GNUNET_CONTAINER_DLL_insert (ctx->jobs_head,
444  ctx->jobs_tail,
445  job);
446  return job;
447 }
448 
449 
450 void
452  const struct curl_slist *extra_headers)
453 {
454  struct curl_slist *all_headers = job->job_headers;
455 
456  for (const struct curl_slist *curr = extra_headers;
457  NULL != curr;
458  curr = curr->next)
459  {
460  GNUNET_assert (NULL !=
461  (all_headers = curl_slist_append (all_headers,
462  curr->data)));
463  }
464  job->job_headers = all_headers;
465 }
466 
467 
468 struct GNUNET_CURL_Job *
470  CURL *eh,
471  const struct curl_slist *job_headers,
473  void *jcc_cls)
474 {
475  struct GNUNET_CURL_Job *job;
476  struct curl_slist *all_headers;
477 
478  GNUNET_assert (NULL != jcc);
479  all_headers = setup_job_headers (ctx,
480  job_headers);
481  if (NULL == (job = setup_job (eh,
482  ctx,
483  all_headers)))
484  return NULL;
485  job->jcc_raw = jcc;
486  job->jcc_raw_cls = jcc_cls;
487  ctx->cb (ctx->cb_cls);
488  return job;
489 }
490 
491 
492 struct GNUNET_CURL_Job *
494  CURL *eh,
495  const struct curl_slist *job_headers,
497  void *jcc_cls)
498 {
499  struct GNUNET_CURL_Job *job;
500  struct curl_slist *all_headers;
501 
502  GNUNET_assert (NULL != jcc);
503  if ( (NULL != ctx->userpass) &&
504  (0 != curl_easy_setopt (eh,
505  CURLOPT_USERPWD,
506  ctx->userpass)) )
507  return NULL;
508  if ( (NULL != ctx->certfile) &&
509  (0 != curl_easy_setopt (eh,
510  CURLOPT_SSLCERT,
511  ctx->certfile)) )
512  return NULL;
513  if ( (NULL != ctx->certtype) &&
514  (0 != curl_easy_setopt (eh,
515  CURLOPT_SSLCERTTYPE,
516  ctx->certtype)) )
517  return NULL;
518  if ( (NULL != ctx->keyfile) &&
519  (0 != curl_easy_setopt (eh,
520  CURLOPT_SSLKEY,
521  ctx->keyfile)) )
522  return NULL;
523  if ( (NULL != ctx->keypass) &&
524  (0 != curl_easy_setopt (eh,
525  CURLOPT_KEYPASSWD,
526  ctx->keypass)) )
527  return NULL;
528 
529  all_headers = setup_job_headers (ctx,
530  job_headers);
531  if (NULL == (job = setup_job (eh,
532  ctx,
533  all_headers)))
534  return NULL;
535 
536  job->jcc = jcc;
537  job->jcc_cls = jcc_cls;
538  ctx->cb (ctx->cb_cls);
539  return job;
540 }
541 
542 
543 struct GNUNET_CURL_Job *
545  CURL *eh,
547  void *jcc_cls)
548 {
549  struct GNUNET_CURL_Job *job;
550  struct curl_slist *job_headers = NULL;
551 
552  GNUNET_assert (NULL != (job_headers =
553  curl_slist_append (NULL,
554  "Content-Type: application/json")));
556  eh,
557  job_headers,
558  jcc,
559  jcc_cls);
560  curl_slist_free_all (job_headers);
561  return job;
562 }
563 
564 
565 struct GNUNET_CURL_Job *
567  CURL *eh,
569  void *jcc_cls)
570 {
571  return GNUNET_CURL_job_add2 (ctx,
572  eh,
573  NULL,
574  jcc,
575  jcc_cls);
576 }
577 
578 
579 void
581 {
582  struct GNUNET_CURL_Context *ctx = job->ctx;
583 
584  GNUNET_CONTAINER_DLL_remove (ctx->jobs_head,
585  ctx->jobs_tail,
586  job);
587  GNUNET_break (CURLM_OK ==
588  curl_multi_remove_handle (ctx->multi,
589  job->easy_handle));
590  curl_easy_cleanup (job->easy_handle);
591  GNUNET_free (job->db.buf);
592  curl_slist_free_all (job->job_headers);
593  ctx->cb (ctx->cb_cls);
594  GNUNET_free (job);
595 }
596 
597 
604 static bool
605 is_json (const char *ct)
606 {
607  const char *semi;
608 
609  /* check for "application/json" exact match */
610  if (0 == strcasecmp (ct,
611  "application/json"))
612  return true;
613  /* check for "application/json;[ANYTHING]" */
614  semi = strchr (ct,
615  ';');
616  /* also allow "application/json [ANYTHING]" (note the space!) */
617  if (NULL == semi)
618  semi = strchr (ct,
619  ' ');
620  if (NULL == semi)
621  return false; /* no delimiter we accept, forget it */
622  if (semi - ct != strlen ("application/json"))
623  return false; /* delimiter past desired length, forget it */
624  if (0 == strncasecmp (ct,
625  "application/json",
626  strlen ("application/json")))
627  return true; /* OK */
628  return false;
629 }
630 
631 
632 void *
634  CURL *eh,
635  long *response_code)
636 {
637  json_t *json;
638  json_error_t error;
639  char *ct;
640 
642  "Downloaded body: %.*s\n",
643  (int) db->buf_size,
644  (char *) db->buf);
645  if (CURLE_OK !=
646  curl_easy_getinfo (eh,
647  CURLINFO_RESPONSE_CODE,
648  response_code))
649  {
650  /* unexpected error... */
651  GNUNET_break (0);
652  *response_code = 0;
653  }
654  if ((CURLE_OK !=
655  curl_easy_getinfo (eh,
656  CURLINFO_CONTENT_TYPE,
657  &ct)) ||
658  (NULL == ct) ||
659  (! is_json (ct)))
660  {
661  /* No content type or explicitly not JSON, refuse to parse
662  (but keep response code) */
663  if (0 != db->buf_size)
665  "Did NOT detect response `%.*s' as JSON\n",
666  (int) db->buf_size,
667  (const char *) db->buf);
668  return NULL;
669  }
670  if (MHD_HTTP_NO_CONTENT == *response_code)
671  return NULL;
672  if (0 == *response_code)
673  {
674  char *url;
675 
676  if (CURLE_OK !=
677  curl_easy_getinfo (eh,
678  CURLINFO_EFFECTIVE_URL,
679  &url))
680  url = "<unknown URL>";
682  "Failed to download response from `%s': \n",
683  url);
684  return NULL;
685  }
686  json = NULL;
687  if (0 == db->eno)
688  {
689  json = json_loadb (db->buf,
690  db->buf_size,
691  JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
692  &error);
693  if (NULL == json)
694  {
695  JSON_WARN (error);
696  *response_code = 0;
697  }
698  }
699  GNUNET_free (db->buf);
700  db->buf = NULL;
701  db->buf_size = 0;
702  return json;
703 }
704 
705 
708  const char *header)
709 {
710  ctx->common_headers = curl_slist_append (ctx->common_headers,
711  header);
712  if (NULL == ctx->common_headers)
713  return GNUNET_SYSERR;
714 
715  return GNUNET_OK;
716 }
717 
718 
719 void
723 {
724  CURLMsg *cmsg;
725  int n_running;
726  int n_completed;
727 
728  (void) curl_multi_perform (ctx->multi,
729  &n_running);
730  while (NULL != (cmsg = curl_multi_info_read (ctx->multi,
731  &n_completed)))
732  {
733  struct GNUNET_CURL_Job *job;
734  long response_code;
735  void *response;
736 
737  /* Only documented return value is CURLMSG_DONE */
738  GNUNET_break (CURLMSG_DONE == cmsg->msg);
739  GNUNET_assert (CURLE_OK ==
740  curl_easy_getinfo (cmsg->easy_handle,
741  CURLINFO_PRIVATE,
742  (char **) &job));
743  GNUNET_assert (job->ctx == ctx);
744  response_code = 0;
745  if (NULL != job->jcc_raw)
746  {
747  /* RAW mode, no parsing */
748  GNUNET_break (CURLE_OK ==
749  curl_easy_getinfo (job->easy_handle,
750  CURLINFO_RESPONSE_CODE,
751  &response_code));
752  job->jcc_raw (job->jcc_raw_cls,
753  response_code,
754  job->db.buf,
755  job->db.buf_size);
756  }
757  else
758  {
759  /* to be parsed via 'rp' */
760  response = rp (&job->db,
761  job->easy_handle,
762  &response_code);
763  job->jcc (job->jcc_cls,
764  response_code,
765  response);
766  rc (response);
767  }
769  }
770 }
771 
772 
773 void
775 {
778  (GNUNET_CURL_ResponseCleaner) & json_decref);
779 }
780 
781 
782 void
784  fd_set *read_fd_set,
785  fd_set *write_fd_set,
786  fd_set *except_fd_set,
787  int *max_fd,
788  long *timeout)
789 {
790  long to;
791  int m;
792 
793  m = -1;
794  GNUNET_assert (CURLM_OK ==
795  curl_multi_fdset (ctx->multi,
796  read_fd_set,
797  write_fd_set,
798  except_fd_set,
799  &m));
800  to = *timeout;
801  *max_fd = GNUNET_MAX (m, *max_fd);
802  GNUNET_assert (CURLM_OK ==
803  curl_multi_timeout (ctx->multi,
804  &to));
805 
806  /* Only if what we got back from curl is smaller than what we
807  already had (-1 == infinity!), then update timeout */
808  if ((to < *timeout) && (-1 != to))
809  *timeout = to;
810  if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
811  *timeout = to;
812 }
813 
814 
815 void
817 {
818  /* all jobs must have been cancelled at this time, assert this */
819  GNUNET_assert (NULL == ctx->jobs_head);
820  curl_share_cleanup (ctx->share);
821  curl_multi_cleanup (ctx->multi);
822  curl_slist_free_all (ctx->common_headers);
823  GNUNET_free (ctx->userpass);
824  GNUNET_free (ctx->certtype);
825  GNUNET_free (ctx->certfile);
826  GNUNET_free (ctx->keyfile);
827  GNUNET_free (ctx->keypass);
828  GNUNET_free (ctx);
829 }
830 
831 
835 __attribute__ ((constructor)) void
836 GNUNET_CURL_constructor__ (void)
837 {
838  CURLcode ret;
839 
840  if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT)))
841  {
843  "curl_global_init",
844  ret);
845  curl_fail = 1;
846  }
847 }
848 
849 
853 __attribute__ ((destructor)) void
854 GNUNET_CURL_destructor__ (void)
855 {
856  if (curl_fail)
857  return;
858  curl_global_cleanup ();
859 }
860 
861 
862 /* end of curl.c */
__attribute__((constructor))
Initial global setup logic, specifically runs the Curl setup.
Definition: curl.c:835
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:605
#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:633
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.
#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:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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:783
void GNUNET_CURL_fini(struct GNUNET_CURL_Context *ctx)
Cleanup library initialisation resources.
Definition: curl.c:816
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:493
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:451
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:566
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:720
void GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
Cancel a job.
Definition: curl.c:580
void GNUNET_CURL_perform(struct GNUNET_CURL_Context *ctx)
Run the main event loop for the CURL interaction.
Definition: curl.c:774
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:544
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:707
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:469
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_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