GNUnet  0.11.x
Data Structures | Typedefs | Functions
CURL integration library

Download JSON using libcurl. More...

Data Structures

struct  GNUNET_CURL_DownloadBuffer
 Buffer data structure we use to buffer the HTTP download before giving it to the JSON parser. More...
 

Typedefs

typedef void(* GNUNET_CURL_RescheduleCallback) (void *cls)
 Function called by the context to ask for the event loop to be rescheduled, that is the application should call GNUNET_CURL_get_select_info() as the set of sockets we care about just changed. More...
 
typedef void *(* GNUNET_CURL_RawParser) (struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
 Parses the raw response we got from the Web server. More...
 
typedef void(* GNUNET_CURL_ResponseCleaner) (void *response)
 Deallocate the response. More...
 
typedef void(* GNUNET_CURL_JobCompletionCallback) (void *cls, long response_code, const void *response)
 Function to call upon completion of a job. More...
 

Functions

struct GNUNET_CURL_ContextGNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
 Initialise this library. More...
 
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. More...
 
int GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header)
 Add custom request header. More...
 
void GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
 Run the main event loop for the CURL interaction. More...
 
void GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, GNUNET_CURL_RawParser rp, GNUNET_CURL_ResponseCleaner rc)
 Run the main event loop for the Taler interaction. More...
 
void GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
 Cleanup library initialisation resources. More...
 
struct GNUNET_CURL_JobGNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, CURL *eh, int add_json, GNUNET_CURL_JobCompletionCallback jcc, void *jcc_cls)
 Schedule a CURL request to be executed and call the given jcc upon its completion. More...
 
struct GNUNET_CURL_JobGNUNET_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. More...
 
void GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
 Cancel a job. More...
 
struct GNUNET_CURL_RescheduleContextGNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx)
 Initialize reschedule context. More...
 
struct GNUNET_CURL_RescheduleContextGNUNET_CURL_gnunet_rc_create_with_parser (struct GNUNET_CURL_Context *ctx, GNUNET_CURL_RawParser rp, GNUNET_CURL_ResponseCleaner rc)
 Initialize reschedule context; with custom response parser. More...
 
void GNUNET_CURL_gnunet_rc_destroy (struct GNUNET_CURL_RescheduleContext *rc)
 Destroy reschedule context. More...
 
void GNUNET_CURL_gnunet_scheduler_reschedule (void *cls)
 Implementation of the GNUNET_CURL_RescheduleCallback for GNUnet's scheduler. More...
 
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. More...
 

Detailed Description

Download JSON using libcurl.

Typedef Documentation

◆ GNUNET_CURL_RescheduleCallback

typedef void(* GNUNET_CURL_RescheduleCallback) (void *cls)

Function called by the context to ask for the event loop to be rescheduled, that is the application should call GNUNET_CURL_get_select_info() as the set of sockets we care about just changed.

Parameters
clsclosure

Definition at line 51 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_RawParser

typedef void*(* GNUNET_CURL_RawParser) (struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)

Parses the raw response we got from the Web server.

Parameters
dbthe raw data
ehhandle
response_codeHTTP response code
Returns
the parsed object

Definition at line 86 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_ResponseCleaner

typedef void(* GNUNET_CURL_ResponseCleaner) (void *response)

Deallocate the response.

Parameters
responseobject to clean

Definition at line 96 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_JobCompletionCallback

typedef void(* GNUNET_CURL_JobCompletionCallback) (void *cls, long response_code, const void *response)

Function to call upon completion of a job.

Parameters
clsclosure
response_codeHTTP response code from server, 0 on hard error
jsonresponse, NULL if response was not in JSON format

Definition at line 203 of file gnunet_curl_lib.h.

Function Documentation

◆ GNUNET_CURL_init()

struct GNUNET_CURL_Context* GNUNET_CURL_init ( GNUNET_CURL_RescheduleCallback  cb,
void *  cb_cls 
)

Initialise this library.

This function should be called before using any of the following functions.

Parameters
cbfunction to call when rescheduling is required
cb_clsclosure for cb
Returns
library context

Definition at line 174 of file curl.c.

References GNUNET_CURL_Context::cb, GNUNET_CURL_Context::cb_cls, GNUNET_CURL_Job::ctx, curl_fail, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_new, GNUNET_CURL_Context::multi, multi, and GNUNET_CURL_Context::share.

175 {
176  struct GNUNET_CURL_Context *ctx;
177  CURLM *multi;
178  CURLSH *share;
179 
180  if (curl_fail)
181  {
182  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Curl was not initialised properly\n");
183  return NULL;
184  }
185  if (NULL == (multi = curl_multi_init ()))
186  {
188  "Failed to create a Curl multi handle\n");
189  return NULL;
190  }
191  if (NULL == (share = curl_share_init ()))
192  {
194  "Failed to create a Curl share handle\n");
195  return NULL;
196  }
197  ctx = GNUNET_new (struct GNUNET_CURL_Context);
198  ctx->cb = cb;
199  ctx->cb_cls = cb_cls;
200  ctx->multi = multi;
201  ctx->share = share;
202  return ctx;
203 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
GNUNET_CURL_RescheduleCallback cb
Function we need to call whenever the event loop's socket set changed.
Definition: curl.c:156
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static CURLM * multi
Current multi-CURL handle.
CURLSH * share
Curl share handle.
Definition: curl.c:129
static int curl_fail
Failsafe flag.
Definition: curl.c:66
Context.
Definition: curl.c:119
CURLM * multi
Curl multi handle.
Definition: curl.c:124
void * cb_cls
Closure for cb.
Definition: curl.c:161
#define GNUNET_log(kind,...)

◆ GNUNET_CURL_get_select_info()

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.

Basically, a client should use this API to prepare for select(), then block on select(), then call GNUNET_CURL_perform() and then start again until the work with the context is done.

This function will NOT zero out the sets and assumes that max_fd and timeout are already set to minimal applicable values. It is safe to give this API FD-sets and max_fd and timeout that are already initialized to some other descriptors that need to go into the select() call.

Parameters
ctxcontext to get the event loop information for
read_fd_setwill be set for any pending read operations
write_fd_setwill be set for any pending write operations
except_fd_setis here because curl_multi_fdset() has this argument
max_fdset to the highest FD included in any set; if the existing sets have no FDs in it, the initial value should be "-1". (Note that max_fd + 1 will need to be passed to select().)
timeoutset to the timeout in milliseconds (!); -1 means no timeout (NULL, blocking forever is OK), 0 means to proceed immediately with GNUNET_CURL_perform().

Note that calling any other GNUNET_CURL-API may also imply that the library is again ready for GNUNET_CURL_perform().

Basically, a client should use this API to prepare for select(), then block on select(), then call GNUNET_CURL_perform() and then start again until the work with the context is done.

This function will NOT zero out the sets and assumes that max_fd and timeout are already set to minimal applicable values. It is safe to give this API FD-sets and max_fd and timeout that are already initialized to some other descriptors that need to go into the select() call.

Parameters
ctxcontext to get the event loop information for
read_fd_setwill be set for any pending read operations
write_fd_setwill be set for any pending write operations
except_fd_setis here because curl_multi_fdset() has this argument
max_fdset to the highest FD included in any set; if the existing sets have no FDs in it, the initial value should be "-1". (Note that max_fd + 1 will need to be passed to select().)
timeoutset to the timeout in milliseconds (!); -1 means no timeout (NULL, blocking forever is OK), 0 means to proceed immediately with GNUNET_CURL_perform().

Definition at line 657 of file curl.c.

References GNUNET_assert, GNUNET_MAX, GNUNET_CURL_Context::jobs_head, m, GNUNET_CURL_Context::multi, and timeout.

Referenced by context_task().

663 {
664  long to;
665  int m;
666 
667  m = -1;
668  GNUNET_assert (CURLM_OK == curl_multi_fdset (ctx->multi,
669  read_fd_set,
670  write_fd_set,
671  except_fd_set,
672  &m));
673  to = *timeout;
674  *max_fd = GNUNET_MAX (m, *max_fd);
675  GNUNET_assert (CURLM_OK == curl_multi_timeout (ctx->multi, &to));
676 
677  /* Only if what we got back from curl is smaller than what we
678  already had (-1 == infinity!), then update timeout */
679  if ((to < *timeout) && (-1 != to))
680  *timeout = to;
681  if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
682  *timeout = to;
683 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:134
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
CURLM * multi
Curl multi handle.
Definition: curl.c:124
Here is the caller graph for this function:

◆ GNUNET_CURL_append_header()

int GNUNET_CURL_append_header ( struct GNUNET_CURL_Context ctx,
const char *  header 
)

Add custom request header.

Parameters
ctxcURL context.
headerheader string; will be given to the context AS IS.
Returns
GNUNET_OK if no errors occurred, GNUNET_SYSERR otherwise.

Definition at line 501 of file curl.c.

References GNUNET_CURL_Context::common_headers, GNUNET_OK, and GNUNET_SYSERR.

502 {
503  ctx->common_headers = curl_slist_append (ctx->common_headers, header);
504  if (NULL == ctx->common_headers)
505  return GNUNET_SYSERR;
506 
507  return GNUNET_OK;
508 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct curl_slist * common_headers
Headers common for all requests in the context.
Definition: curl.c:144

◆ GNUNET_CURL_perform()

void GNUNET_CURL_perform ( struct GNUNET_CURL_Context ctx)

Run the main event loop for the CURL interaction.

Parameters
ctxthe library context

Run the main event loop for the CURL interaction.

Parameters
ctxthe library context

Definition at line 620 of file curl.c.

References GNUNET_CURL_download_get_result_(), and GNUNET_CURL_perform2().

621 {
624  (GNUNET_CURL_ResponseCleaner) & json_decref);
625 }
void(* GNUNET_CURL_ResponseCleaner)(void *response)
Deallocate the response.
void GNUNET_CURL_perform2(struct GNUNET_CURL_Context *ctx, GNUNET_CURL_RawParser rp, GNUNET_CURL_ResponseCleaner rc)
Run the main event loop for the Taler interaction.
Definition: curl.c:520
void * GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Obtain information about the final result about the HTTP download.
Definition: curl.c:433
Here is the call graph for this function:

◆ GNUNET_CURL_perform2()

void GNUNET_CURL_perform2 ( struct GNUNET_CURL_Context ctx,
GNUNET_CURL_RawParser  rp,
GNUNET_CURL_ResponseCleaner  rc 
)

Run the main event loop for the Taler interaction.

Parameters
ctxthe library context
rpparses the raw response returned from the Web server.
rccleans/frees the response

Definition at line 520 of file curl.c.

References UrlRequestData::bytes_received, UrlRequestData::bytes_sent, UrlRequestData::count, get_url_benchmark_data(), GNUNET_assert, GNUNET_break, GNUNET_CURL_job_cancel(), GNUNET_TIME_relative_add(), GNUNET_TIME_relative_max(), job, GNUNET_CURL_Context::multi, GNUNET_TIME_Relative::rel_value_us, response, rp, UrlRequestData::time, and UrlRequestData::time_max.

Referenced by context_task(), and GNUNET_CURL_perform().

523 {
524  CURLMsg *cmsg;
525  int n_running;
526  int n_completed;
527 
528  (void) curl_multi_perform (ctx->multi, &n_running);
529  while (NULL != (cmsg = curl_multi_info_read (ctx->multi, &n_completed)))
530  {
531  struct GNUNET_CURL_Job *job;
532  long response_code;
533  void *response;
534 
535  /* Only documented return value is CURLMSG_DONE */
536  GNUNET_break (CURLMSG_DONE == cmsg->msg);
537  GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
538  CURLINFO_PRIVATE,
539  (char **) &job));
540  GNUNET_assert (job->ctx == ctx);
541  response_code = 0;
542  response = rp (&job->db, job->easy_handle, &response_code);
543 #if ENABLE_BENCHMARK
544  {
545  char *url = NULL;
546  double total_as_double = 0;
547  struct GNUNET_TIME_Relative total;
548  struct UrlRequestData *urd;
549  /* Some care required, as curl is using data types (long vs curl_off_t vs
550  * double) inconsistently to store byte count. */
551  curl_off_t size_curl = 0;
552  long size_long = 0;
553  uint64_t bytes_sent = 0;
554  uint64_t bytes_received = 0;
555 
556  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
557  CURLINFO_TOTAL_TIME,
558  &total_as_double));
559  total.rel_value_us = total_as_double * 1000 * 1000;
560 
561  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
562  CURLINFO_EFFECTIVE_URL,
563  &url));
564 
565  /* HEADER_SIZE + SIZE_DOWNLOAD_T is hopefully the total
566  number of bytes received, not clear from curl docs. */
567 
568  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
569  CURLINFO_HEADER_SIZE,
570  &size_long));
571  bytes_received += size_long;
572 
573  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
574  CURLINFO_SIZE_DOWNLOAD_T,
575  &size_curl));
576  bytes_received += size_curl;
577 
578  /* REQUEST_SIZE + SIZE_UPLOAD_T is hopefully the total number of bytes
579  sent, again docs are not completely clear. */
580 
581  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
582  CURLINFO_REQUEST_SIZE,
583  &size_long));
584  bytes_sent += size_long;
585 
586  /* We obtain this value to check an invariant, but never use it otherwise. */
587  GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
588  CURLINFO_SIZE_UPLOAD_T,
589  &size_curl));
590 
591  /* CURLINFO_SIZE_UPLOAD_T <= CURLINFO_REQUEST_SIZE should
592  be an invariant.
593  As verified with
594  curl -w "foo%{size_request} -XPOST --data "ABC" $URL
595  the CURLINFO_REQUEST_SIZE should be the whole size of the request
596  including headers and body.
597  */GNUNET_break (size_curl <= size_long);
598 
599  urd = get_url_benchmark_data (url, (unsigned int) response_code);
600  urd->count++;
601  urd->time = GNUNET_TIME_relative_add (urd->time, total);
602  urd->time_max = GNUNET_TIME_relative_max (total, urd->time_max);
603  urd->bytes_sent += bytes_sent;
605  }
606 #endif
607  job->jcc (job->jcc_cls, response_code, response);
608  rc (response);
610  }
611 }
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Struct for benchmark data for one URL.
Definition: benchmark.h:65
struct GNUNET_TIME_Relative time_max
Slowest time to response.
Definition: benchmark.h:100
void GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
Cancel a job.
Definition: curl.c:400
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint64_t count
How often was the URL requested?
Definition: benchmark.h:80
void * jcc_cls
Closure for jcc.
Definition: curl.c:101
GNUNET_CURL_JobCompletionCallback jcc
Function to call upon completion.
Definition: curl.c:96
uint64_t bytes_sent
How many bytes were sent in total to request the URL.
Definition: benchmark.h:85
struct GNUNET_TIME_Relative time
Total time spent requesting this URL.
Definition: benchmark.h:95
CURLM * multi
Curl multi handle.
Definition: curl.c:124
uint64_t bytes_received
How many bytes were received in total as response to requesting this URL.
Definition: benchmark.h:90
CURL * easy_handle
Easy handle of the job.
Definition: curl.c:86
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
Definition: gnunet-cadet.c:137
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:579
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition: curl.c:71
static char * rp
Relying party.
static struct MHD_Response * response
Our canonical response.
struct GNUNET_CURL_DownloadBuffer db
Buffer for response received from CURL.
Definition: curl.c:106
struct UrlRequestData * get_url_benchmark_data(char *url, unsigned int status)
Get benchmark data for a URL.
Definition: benchmark.c:241
struct GNUNET_CURL_Context * ctx
Context this job runs in.
Definition: curl.c:91
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CURL_fini()

void GNUNET_CURL_fini ( struct GNUNET_CURL_Context ctx)

Cleanup library initialisation resources.

This function should be called after using this library to cleanup the resources occupied during library's initialisation.

Parameters
ctxthe library context

Definition at line 694 of file curl.c.

References GNUNET_CURL_Context::common_headers, GNUNET_assert, GNUNET_free, GNUNET_CURL_Context::jobs_head, GNUNET_CURL_Context::multi, and GNUNET_CURL_Context::share.

695 {
696  /* all jobs must have been cancelled at this time, assert this */
697  GNUNET_assert (NULL == ctx->jobs_head);
698  curl_share_cleanup (ctx->share);
699  curl_multi_cleanup (ctx->multi);
700  curl_slist_free_all (ctx->common_headers);
701  GNUNET_free (ctx);
702 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:134
CURLSH * share
Curl share handle.
Definition: curl.c:129
CURLM * multi
Curl multi handle.
Definition: curl.c:124
#define GNUNET_free(ptr)
Wrapper around free.
struct curl_slist * common_headers
Headers common for all requests in the context.
Definition: curl.c:144

◆ GNUNET_CURL_job_add()

struct GNUNET_CURL_Job* GNUNET_CURL_job_add ( struct GNUNET_CURL_Context ctx,
CURL *  eh,
int  add_json,
GNUNET_CURL_JobCompletionCallback  jcc,
void *  jcc_cls 
)

Schedule a CURL request to be executed and call the given jcc upon its completion.

Note that the context will make use of the CURLOPT_PRIVATE facility of the CURL eh.

This function modifies the CURL handle to add the "Content-Type: application/json" header if add_json is set.

Parameters
ctxcontext to execute the job in
ehcurl easy handle for the request, will be executed AND cleaned up
add_jsonadd "application/json" content type header
jcccallback to invoke upon completion
jcc_clsclosure for jcc
Returns
NULL on error (in this case, is still released!)

Definition at line 371 of file curl.c.

References GNUNET_assert, GNUNET_CURL_job_add2(), GNUNET_YES, job, and GNUNET_CURL_Job::job_headers.

376 {
377  struct GNUNET_CURL_Job *job;
378  struct curl_slist *job_headers = NULL;
379 
380  if (GNUNET_YES == add_json)
381  {
382  GNUNET_assert (
383  NULL != (job_headers =
384  curl_slist_append (NULL, "Content-Type: application/json")));
385  }
386 
387  job = GNUNET_CURL_job_add2 (ctx, eh, job_headers, jcc, jcc_cls);
388  curl_slist_free_all (job_headers);
389  return job;
390 }
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:279
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
Definition: gnunet-cadet.c:137
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition: curl.c:71
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:

◆ GNUNET_CURL_job_add2()

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.

Note that the context will make use of the CURLOPT_PRIVATE facility of the CURL eh.

This function modifies the CURL handle to add the "Content-Type: application/json" header if add_json is set.

Parameters
ctxcontext to execute the job in
ehcurl easy handle for the request, will be executed AND cleaned up
job_headersextra headers to add for this request
jcccallback to invoke upon completion
jcc_clsclosure for jcc
Returns
NULL on error (in this case, is still released!)

Note that the context will make use of the CURLOPT_PRIVATE facility of the CURL eh.

This function modifies the CURL handle to add the "Content-Type: application/json" header if add_json is set.

Parameters
ctxcontext to execute the job in
ehcurl easy handle for the request, will be executed AND cleaned up. NOTE: the handle should never have gotten any headers list, as that would then be ovverridden by jcc. Therefore, always pass custom headers as the job_headers parameter.
job_headersextra headers to add for this request
jcccallback to invoke upon completion
jcc_clsclosure for jcc
Returns
NULL on error (in this case, is still released!)

Definition at line 279 of file curl.c.

References GNUNET_CURL_Context::async_scope_id_header, GNUNET_CURL_Context::cb, GNUNET_CURL_Context::cb_cls, GNUNET_CURL_Context::common_headers, GNUNET_CURL_Job::ctx, GNUNET_CURL_Job::db, download_cb(), GNUNET_CURL_Job::easy_handle, GNUNET_assert, GNUNET_async_scope_get(), GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_new, GNUNET_STRINGS_data_to_string_alloc(), GNUNET_YES, GNUNET_AsyncScopeSave::have_scope, GNUNET_CURL_Job::jcc, GNUNET_CURL_Job::jcc_cls, job, GNUNET_CURL_Job::job_headers, GNUNET_CURL_Context::jobs_head, GNUNET_CURL_Context::jobs_tail, GNUNET_CURL_Context::multi, GNUNET_AsyncScopeSave::scope_id, and GNUNET_CURL_Context::share.

Referenced by GNUNET_CURL_job_add().

284 {
285  struct GNUNET_CURL_Job *job;
286  struct curl_slist *all_headers = NULL;
287 
288  for (const struct curl_slist *curr = job_headers; curr != NULL;
289  curr = curr->next)
290  {
291  GNUNET_assert (NULL !=
292  (all_headers = curl_slist_append (all_headers, curr->data)));
293  }
294 
295  for (const struct curl_slist *curr = ctx->common_headers; curr != NULL;
296  curr = curr->next)
297  {
298  GNUNET_assert (NULL !=
299  (all_headers = curl_slist_append (all_headers, curr->data)));
300  }
301 
302  if (NULL != ctx->async_scope_id_header)
303  {
305 
307  if (GNUNET_YES == scope.have_scope)
308  {
309  char *aid_header = NULL;
310  aid_header =
312  sizeof(
313  struct GNUNET_AsyncScopeId));
314  GNUNET_assert (NULL != aid_header);
315  GNUNET_assert (NULL != curl_slist_append (all_headers, aid_header));
316  GNUNET_free (aid_header);
317  }
318  }
319 
320  if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers))
321  {
322  GNUNET_break (0);
323  curl_slist_free_all (all_headers);
324  curl_easy_cleanup (eh);
325  return NULL;
326  }
327 
328  job = GNUNET_new (struct GNUNET_CURL_Job);
329  job->job_headers = all_headers;
330 
331  if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) ||
332  (CURLE_OK !=
333  curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) ||
334  (CURLE_OK != curl_easy_setopt (eh, CURLOPT_WRITEDATA, &job->db)) ||
335  (CURLE_OK != curl_easy_setopt (eh, CURLOPT_SHARE, ctx->share)) ||
336  (CURLM_OK != curl_multi_add_handle (ctx->multi, eh)))
337  {
338  GNUNET_break (0);
339  GNUNET_free (job);
340  curl_easy_cleanup (eh);
341  return NULL;
342  }
343 
344  job->easy_handle = eh;
345  job->ctx = ctx;
346  job->jcc = jcc;
347  job->jcc_cls = jcc_cls;
349  ctx->cb (ctx->cb_cls);
350  return job;
351 }
#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_new(type)
Allocate a struct or union of the given type.
Identifier for an asynchronous execution context.
GNUNET_CURL_RescheduleCallback cb
Function we need to call whenever the event loop&#39;s socket set changed.
Definition: curl.c:156
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void * jcc_cls
Closure for jcc.
Definition: curl.c:101
GNUNET_CURL_JobCompletionCallback jcc
Function to call upon completion.
Definition: curl.c:96
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:134
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
CURLSH * share
Curl share handle.
Definition: curl.c:129
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
CURLM * multi
Curl multi handle.
Definition: curl.c:124
Saved async scope identifier or root scope.
CURL * easy_handle
Easy handle of the job.
Definition: curl.c:86
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
Definition: gnunet-cadet.c:137
void * cb_cls
Closure for cb.
Definition: curl.c:161
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition: curl.c:71
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:150
struct GNUNET_CURL_Job * jobs_tail
We keep jobs in a DLL.
Definition: curl.c:139
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CURL_DownloadBuffer db
Buffer for response received from CURL.
Definition: curl.c:106
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:920
struct curl_slist * job_headers
Headers used for this job, the list needs to be freed after the job has finished. ...
Definition: curl.c:112
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CURL_Context * ctx
Context this job runs in.
Definition: curl.c:91
struct curl_slist * common_headers
Headers common for all requests in the context.
Definition: curl.c:144
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:234
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CURL_job_cancel()

void GNUNET_CURL_job_cancel ( struct GNUNET_CURL_Job job)

Cancel a job.

Must only be called before the job completion callback is called for the respective job.

Parameters
jobjob to cancel

Definition at line 400 of file curl.c.

References GNUNET_CURL_DownloadBuffer::buf, GNUNET_CURL_Job::ctx, GNUNET_CURL_Job::db, GNUNET_CURL_Job::easy_handle, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_free_non_null, GNUNET_CURL_Job::job_headers, GNUNET_CURL_Context::jobs_head, GNUNET_CURL_Context::jobs_tail, and GNUNET_CURL_Context::multi.

Referenced by GNUNET_CURL_perform2().

401 {
402  struct GNUNET_CURL_Context *ctx = job->ctx;
403 
405  GNUNET_break (CURLM_OK ==
406  curl_multi_remove_handle (ctx->multi, job->easy_handle));
407  curl_easy_cleanup (job->easy_handle);
408  GNUNET_free_non_null (job->db.buf);
409  curl_slist_free_all (job->job_headers);
410  GNUNET_free (job);
411 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_CURL_Job * jobs_head
We keep jobs in a DLL.
Definition: curl.c:134
Context.
Definition: curl.c:119
CURLM * multi
Curl multi handle.
Definition: curl.c:124
CURL * easy_handle
Easy handle of the job.
Definition: curl.c:86
void * buf
Download buffer.
struct GNUNET_CURL_Job * jobs_tail
We keep jobs in a DLL.
Definition: curl.c:139
struct GNUNET_CURL_DownloadBuffer db
Buffer for response received from CURL.
Definition: curl.c:106
struct curl_slist * job_headers
Headers used for this job, the list needs to be freed after the job has finished. ...
Definition: curl.c:112
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CURL_Context * ctx
Context this job runs in.
Definition: curl.c:91
Here is the caller graph for this function:

◆ GNUNET_CURL_gnunet_rc_create()

struct GNUNET_CURL_RescheduleContext* GNUNET_CURL_gnunet_rc_create ( struct GNUNET_CURL_Context ctx)

Initialize reschedule context.

Parameters
ctxcontext to manage
Returns
closure for GNUNET_CURL_gnunet_scheduler_reschedule().

Definition at line 103 of file curl_reschedule.c.

References clean_result(), GNUNET_CURL_RescheduleContext::cleaner, GNUNET_CURL_RescheduleContext::ctx, GNUNET_CURL_download_get_result_(), GNUNET_new, and GNUNET_CURL_RescheduleContext::parser.

104 {
106 
108  rc->ctx = ctx;
110  rc->cleaner = &clean_result;
111  return rc;
112 }
struct GNUNET_CURL_Context * ctx
Context we manage.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
GNUNET_CURL_ResponseCleaner cleaner
Deallocate the response object.
GNUNET_CURL_RawParser parser
Parser of the raw response.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Closure for GNUNET_CURL_gnunet_scheduler_reschedule().
static void clean_result(void *response)
Just a wrapper to avoid casting of function pointers.
void * GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Obtain information about the final result about the HTTP download.
Definition: curl.c:433
Here is the call graph for this function:

◆ GNUNET_CURL_gnunet_rc_create_with_parser()

struct GNUNET_CURL_RescheduleContext* GNUNET_CURL_gnunet_rc_create_with_parser ( struct GNUNET_CURL_Context ctx,
GNUNET_CURL_RawParser  rp,
GNUNET_CURL_ResponseCleaner  rc 
)

Initialize reschedule context; with custom response parser.

Parameters
ctxcontext to manage
Returns
closure for GNUNET_CURL_gnunet_scheduler_reschedule().

Definition at line 69 of file curl_reschedule.c.

References GNUNET_CURL_RescheduleContext::cleaner, GNUNET_CURL_RescheduleContext::ctx, GNUNET_new, GNUNET_CURL_RescheduleContext::parser, and rp.

72 {
73  struct GNUNET_CURL_RescheduleContext *rctx;
74 
76  rctx->ctx = ctx;
77  rctx->parser = rp;
78  rctx->cleaner = rc;
79 
80  return rctx;
81 }
struct GNUNET_CURL_Context * ctx
Context we manage.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
GNUNET_CURL_ResponseCleaner cleaner
Deallocate the response object.
GNUNET_CURL_RawParser parser
Parser of the raw response.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Closure for GNUNET_CURL_gnunet_scheduler_reschedule().
static char * rp
Relying party.

◆ GNUNET_CURL_gnunet_rc_destroy()

void GNUNET_CURL_gnunet_rc_destroy ( struct GNUNET_CURL_RescheduleContext rc)

Destroy reschedule context.

Parameters
rccontext to destroy

Definition at line 121 of file curl_reschedule.c.

References GNUNET_free, GNUNET_SCHEDULER_cancel(), and GNUNET_CURL_RescheduleContext::task.

122 {
123  if (NULL != rc->task)
125  GNUNET_free (rc);
126 }
struct GNUNET_SCHEDULER_Task * task
Just the task.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:

◆ GNUNET_CURL_gnunet_scheduler_reschedule()

void GNUNET_CURL_gnunet_scheduler_reschedule ( void *  cls)

Implementation of the GNUNET_CURL_RescheduleCallback for GNUnet's scheduler.

Will run the CURL context using GNUnet's scheduler. Note that you MUST immediately destroy the reschedule context after calling GNUNET_CURL_fini().

Parameters
clsmust point to a struct GNUNET_CURL_RescheduleContext * (pointer to a pointer!)

Definition at line 191 of file curl_reschedule.c.

References context_task(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), and GNUNET_CURL_RescheduleContext::task.

192 {
193  struct GNUNET_CURL_RescheduleContext *rc = *(void **) cls;
194 
195  if (NULL != rc->task)
198 }
Closure for GNUNET_CURL_gnunet_scheduler_reschedule().
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
struct GNUNET_SCHEDULER_Task * task
Just the task.
static void context_task(void *cls)
Task that runs the context&#39;s event loop with the GNUnet scheduler.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:

◆ GNUNET_CURL_enable_async_scope_header()

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.

Parameters
ctxthe context to enable this for
header_namename of the header to send.

Definition at line 213 of file curl.c.

References GNUNET_CURL_Context::async_scope_id_header.

215 {
216  ctx->async_scope_id_header = header_name;
217 }
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:150