GNUnet 0.28.1-dev.5-1-gae1c02d74
 
Loading...
Searching...
No Matches
CURL integration library

Download JSON using libcurl. More...

Collaboration diagram for CURL integration library:

Data Structures

struct  GNUNET_CURL_DownloadBuffer
 Buffer data structure we use to buffer the HTTP download before giving it to the JSON parser. More...
 
struct  GNUNET_CURL_StreamHandlers
 What to call for a job added with GNUNET_CURL_job_add_stream(). More...
 

Macros

#define GNUNET_CURL_STREAM_PAUSE   CURL_WRITEFUNC_PAUSE
 Return value from a GNUNET_CURL_StreamCallback asking for delivery to stop until GNUNET_CURL_job_set_paused() is called.
 

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.
 
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.
 
typedef void(* GNUNET_CURL_ResponseCleaner) (void *response)
 Deallocate the response.
 
typedef void(* GNUNET_CURL_JobCompletionCallback) (void *cls, long response_code, const void *response)
 Function to call upon completion of a job.
 
typedef 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.
 
typedef enum GNUNET_GenericReturnValue(* GNUNET_CURL_StreamHeaderCallback) (void *cls, const char *line, size_t line_size)
 Function called with one raw header line of the response, as it arrives.
 
typedef size_t(* GNUNET_CURL_StreamCallback) (void *cls, const void *data, size_t data_size)
 Function called with a chunk of the response body as it arrives.
 

Functions

struct GNUNET_CURL_ContextGNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
 Initialise this library.
 
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.
 
enum GNUNET_GenericReturnValue GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header)
 Add custom request header.
 
void GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
 Run the main event loop for the CURL interaction.
 
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.
 
void GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
 Cleanup library initialisation resources.
 
struct GNUNET_CURL_JobGNUNET_CURL_job_add_stream (struct GNUNET_CURL_Context *ctx, CURL *eh, const struct curl_slist *job_headers, const struct GNUNET_CURL_StreamHandlers *sh)
 Schedule a CURL request whose response is delivered incrementally, rather than buffered in full and handed over at the end.
 
void GNUNET_CURL_job_set_paused (struct GNUNET_CURL_Job *job, bool recv_paused, bool send_paused)
 Say which directions of job are to be paused from now on.
 
struct GNUNET_CURL_JobGNUNET_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.
 
struct GNUNET_CURL_JobGNUNET_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.
 
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 performed with ctx.
 
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 performed with ctx.
 
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.
 
struct GNUNET_CURL_JobGNUNET_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.
 
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.
 
void GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
 Cancel a job.
 
struct GNUNET_CURL_RescheduleContextGNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx)
 Initialize reschedule context.
 
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.
 
void GNUNET_CURL_gnunet_rc_destroy (struct GNUNET_CURL_RescheduleContext *rc)
 Destroy reschedule context.
 
void GNUNET_CURL_gnunet_scheduler_reschedule (void *cls)
 Implementation of the GNUNET_CURL_RescheduleCallback for GNUnet's scheduler.
 
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.
 
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.
 

Detailed Description

Download JSON using libcurl.

Macro Definition Documentation

◆ GNUNET_CURL_STREAM_PAUSE

#define GNUNET_CURL_STREAM_PAUSE   CURL_WRITEFUNC_PAUSE

Return value from a GNUNET_CURL_StreamCallback asking for delivery to stop until GNUNET_CURL_job_set_paused() is called.

Nothing is lost: the same bytes are offered again after the job is resumed.

Definition at line 257 of file gnunet_curl_lib.h.

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 48 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 83 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 93 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
responsein JSON, NULL if response was not in JSON format

Definition at line 200 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_RawJobCompletionCallback

typedef 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.

Parameters
clsclosure
response_codeHTTP response code from server, 0 on hard error
bodyhttp body of the response
body_sizenumber of bytes in body

Definition at line 214 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_StreamHeaderCallback

typedef enum GNUNET_GenericReturnValue(* GNUNET_CURL_StreamHeaderCallback) (void *cls, const char *line, size_t line_size)

Function called with one raw header line of the response, as it arrives.

Only used by GNUNET_CURL_job_add_stream().

Everything the server sends in a header section is passed on, which is more than just the fields of the final response:

  • the status line ("HTTP/1.1 200 OK") of every response, including the interim (1xx) ones and any that libcurl handles internally, such as an authentication round it replays;
  • the empty line that terminates each header section;
  • trailer fields, which arrive after the body and are indented from the header fields only by having come after that empty line.

A caller that wants "the headers of the final response" therefore has to track which section it is in; there is no other way to tell a trailer from a header, or a 1xx field from a real one.

Parameters
clsclosure
linethe header line; NOT 0-terminated, and still carrying its CRLF
line_sizenumber of bytes in line
Returns
GNUNET_OK to continue the transfer, GNUNET_SYSERR to fail it

Definition at line 214 of file gnunet_curl_lib.h.

◆ GNUNET_CURL_StreamCallback

typedef size_t(* GNUNET_CURL_StreamCallback) (void *cls, const void *data, size_t data_size)

Function called with a chunk of the response body as it arrives.

Only used by GNUNET_CURL_job_add_stream().

Parameters
clsclosure
datathe bytes
data_sizenumber of bytes in data
Returns
data_size to accept the chunk, GNUNET_CURL_STREAM_PAUSE to stop delivery until GNUNET_CURL_job_set_paused() is called; returning any other value fails the transfer

Definition at line 272 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 259 of file curl.c.

261{
262 struct GNUNET_CURL_Context *ctx;
263 CURLM *multi;
264 CURLSH *share;
265
266 if (curl_fail)
267 {
269 "Curl was not initialised properly\n");
270 return NULL;
271 }
272 if (NULL == (multi = curl_multi_init ()))
273 {
275 "Failed to create a Curl multi handle\n");
276 return NULL;
277 }
278 if (NULL == (share = curl_share_init ()))
279 {
281 "Failed to create a Curl share handle\n");
282 return NULL;
283 }
285 ctx->cb = cb;
286 ctx->cb_cls = cb_cls;
287 ctx->multi = multi;
288 ctx->share = share;
289 return ctx;
290}
static int curl_fail
Failsafe flag.
Definition curl.c:72
static CURLM * multi
Current multi-CURL handle.
static struct GNUNET_FS_Handle * ctx
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void * cb_cls
Closure for cb.
Definition curl.c:194
CURLSH * share
Curl share handle.
Definition curl.c:162
GNUNET_CURL_RescheduleCallback cb
Function we need to call whenever the event loop's socket set changed.
Definition curl.c:189

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

◆ 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().

Definition at line 1040 of file curl.c.

1046{
1047 long to;
1048 int m;
1049
1050 m = -1;
1051 GNUNET_assert (CURLM_OK ==
1052 curl_multi_fdset (ctx->multi,
1053 read_fd_set,
1054 write_fd_set,
1055 except_fd_set,
1056 &m));
1057 to = *timeout;
1058 *max_fd = GNUNET_MAX (m, *max_fd);
1059 GNUNET_assert (CURLM_OK ==
1060 curl_multi_timeout (ctx->multi,
1061 &to));
1062
1063 /* Only if what we got back from curl is smaller than what we
1064 already had (-1 == infinity!), then update timeout */
1065 if ((to < *timeout) && (-1 != to))
1066 *timeout = to;
1067 if ((-1 == (*timeout)) && (NULL != ctx->jobs_head))
1068 *timeout = to;
1069}
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition gnunet-arm.c:118
#define GNUNET_MAX(a, b)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References ctx, GNUNET_assert, GNUNET_MAX, m, and timeout.

Referenced by context_task().

Here is the caller graph for this function:

◆ GNUNET_CURL_append_header()

enum GNUNET_GenericReturnValue 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 909 of file curl.c.

911{
912 struct curl_slist *job_headers;
913
914 job_headers = curl_slist_append (ctx->common_headers,
915 header);
916 if (NULL == job_headers)
917 {
918 GNUNET_break (0);
919 return GNUNET_SYSERR;
920 }
921 ctx->common_headers = job_headers;
922 return GNUNET_OK;
923}
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.

References ctx, GNUNET_break, GNUNET_OK, and GNUNET_SYSERR.

◆ 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

Definition at line 1031 of file curl.c.

1032{
1035 (GNUNET_CURL_ResponseCleaner) & json_decref);
1036}
void * GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db, CURL *eh, long *response_code)
Definition curl.c:820
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 HTTP interaction.
Definition curl.c:927

References ctx, GNUNET_CURL_download_get_result_(), and GNUNET_CURL_perform2().

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 HTTP interaction.

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

Definition at line 927 of file curl.c.

930{
931 CURLMsg *cmsg;
932 int n_running;
933 int n_completed;
934
935 (void) curl_multi_perform (ctx->multi,
936 &n_running);
937 while (NULL != (cmsg = curl_multi_info_read (ctx->multi,
938 &n_completed)))
939 {
940 struct GNUNET_CURL_Job *job;
942 long response_code;
943 void *response;
944
945 /* Only documented return value is CURLMSG_DONE */
946 GNUNET_break (CURLMSG_DONE == cmsg->msg);
947 GNUNET_assert (CURLE_OK ==
948 curl_easy_getinfo (cmsg->easy_handle,
949 CURLINFO_PRIVATE,
950 (char **) &job));
951 GNUNET_assert (job->ctx == ctx);
952 response_code = 0;
954 if (job->streaming)
955 {
956 /* Body already delivered chunk by chunk; nothing was kept, so
957 the completion callback is told about the outcome only.
958
959 A streaming caller has forwarded the status line and part of
960 the body long before this runs, so the one thing it still
961 needs to know is whether the transfer actually finished --
962 and a transfer that died mid-body still has a perfectly good
963 CURLINFO_RESPONSE_CODE from the status line libcurl parsed at
964 the start. Reporting that would say "200 OK" about a
965 connection that was cut in half. Report the hard error
966 instead, and leave telling the two apart to the caller, which
967 knows whether it has already committed to a status. */
968 if (CURLE_OK != cmsg->data.result)
969 {
971 "Streaming transfer failed: %s\n",
972 curl_easy_strerror (cmsg->data.result));
973 }
974 else
975 {
976 GNUNET_break (CURLE_OK ==
977 curl_easy_getinfo (job->easy_handle,
978 CURLINFO_RESPONSE_CODE,
979 &response_code));
980 }
981 job->sh.jcc (job->sh.jcc_cls,
982 response_code,
983 NULL,
984 0);
985 }
986 else if (NULL != job->jcc_raw)
987 {
988 /* RAW mode, no parsing */
989 GNUNET_break (CURLE_OK ==
990 curl_easy_getinfo (job->easy_handle,
991 CURLINFO_RESPONSE_CODE,
992 &response_code));
993 job->jcc_raw (job->jcc_raw_cls,
994 response_code,
995 job->db.buf,
996 job->db.buf_size);
997 }
998 else
999 {
1000 /* to be parsed via 'rp' */
1001 response = rp (&job->db,
1002 job->easy_handle,
1003 &response_code);
1004 job->jcc (job->jcc_cls,
1005 response_code,
1006 response);
1007 rc (response);
1008 }
1009 {
1010 const char *url = NULL;
1011
1012 if (CURLE_UNKNOWN_OPTION ==
1013 curl_easy_getinfo (job->easy_handle,
1014 CURLINFO_EFFECTIVE_URL,
1015 &url))
1016 url = "<unknown>";
1018 "HTTP request for `%s' finished with %u after %s\n",
1019 url,
1020 (unsigned int) response_code,
1022 true));
1023 /* Note: we MUST NOT free 'url' here */
1024 }
1026 }
1027}
static struct GNUNET_SCHEDULER_Task * job
Task for main job.
static struct MHD_Response * response
Our canonical response.
static char * rp
Relying party.
static struct GNUNET_TIME_Relative duration
Option '-d': duration of the mapping.
Definition gnunet-vpn.c:90
void GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
Cancel a job.
Definition curl.c:767
@ GNUNET_ERROR_TYPE_INFO
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:438
Jobs are CURL requests running within a struct GNUNET_CURL_Context.
Definition curl.c:78
Time for relative time used by GNUnet, in microseconds.

References ctx, duration, GNUNET_assert, GNUNET_break, GNUNET_CURL_job_cancel(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative2s(), job, response, and rp.

Referenced by context_task(), and GNUNET_CURL_perform().

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 1073 of file curl.c.

1074{
1075 /* all jobs must have been cancelled at this time, assert this */
1076 GNUNET_assert (NULL == ctx->jobs_head);
1077 curl_share_cleanup (ctx->share);
1078 curl_multi_cleanup (ctx->multi);
1079 curl_slist_free_all (ctx->common_headers);
1080 GNUNET_free (ctx->userpass);
1081 GNUNET_free (ctx->certtype);
1082 GNUNET_free (ctx->certfile);
1083 GNUNET_free (ctx->keyfile);
1084 GNUNET_free (ctx->keypass);
1085 GNUNET_free (ctx);
1086}
#define GNUNET_free(ptr)
Wrapper around free.

References ctx, GNUNET_assert, and GNUNET_free.

◆ GNUNET_CURL_job_add_stream()

struct GNUNET_CURL_Job * GNUNET_CURL_job_add_stream ( struct GNUNET_CURL_Context ctx,
CURL *  eh,
const struct curl_slist *  job_headers,
const struct GNUNET_CURL_StreamHandlers sh 
)

Schedule a CURL request whose response is delivered incrementally, rather than buffered in full and handed over at the end.

Use this when the response may be larger than memory, or when it has to start reaching its own consumer before the server has finished sending it. GNUNET_CURL_job_add_raw() is the buffering counterpart and remains the right choice for anything that fits.

The job takes over CURLOPT_WRITEFUNCTION, CURLOPT_WRITEDATA, CURLOPT_HEADERFUNCTION, CURLOPT_HEADERDATA and CURLOPT_PRIVATE on eh; setting any of them on the caller's side has no effect. CURLOPT_READFUNCTION is left alone, so a request body is still the caller's to supply, and it may pause the upload with CURL_READFUNC_PAUSE and resume it with GNUNET_CURL_job_set_paused().

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
shwhat to call as the response arrives; copied, so it need not outlive this call
Returns
NULL on error (in this case, eh is still released!)

Definition at line 633 of file curl.c.

637{
638 struct GNUNET_CURL_Job *job;
639 struct curl_slist *all_headers;
640
641 GNUNET_assert (NULL != sh);
642 GNUNET_assert (NULL != sh->scb);
643 GNUNET_assert (NULL != sh->jcc);
644 all_headers = setup_job_headers (ctx,
645 job_headers);
646 if (NULL == (job = setup_job (eh,
647 ctx,
648 all_headers,
649 sh)))
650 return NULL;
651 ctx->cb (ctx->cb_cls);
652 return job;
653}
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:364
static struct GNUNET_CURL_Job * setup_job(CURL *eh, struct GNUNET_CURL_Context *ctx, struct curl_slist *all_headers, const struct GNUNET_CURL_StreamHandlers *sh)
Create a job.
Definition curl.c:525
static struct GNUNET_IDENTITY_Handle * sh
Handle to IDENTITY service.

References ctx, GNUNET_assert, job, setup_job(), setup_job_headers(), and sh.

Here is the call graph for this function:

◆ GNUNET_CURL_job_set_paused()

void GNUNET_CURL_job_set_paused ( struct GNUNET_CURL_Job job,
bool  recv_paused,
bool  send_paused 
)

Say which directions of job are to be paused from now on.

A job pauses itself by returning GNUNET_CURL_STREAM_PAUSE from its GNUNET_CURL_StreamCallback, or CURL_READFUNC_PAUSE from its CURLOPT_READFUNCTION; this is how it is let go again. The state is absolute, not a change: pass what should be true afterwards, so resuming everything is (false, false) and resuming only the receive side of a job whose send side is still paused is (false, true).

Deliberately not a "which direction(s) to resume" bitmask, which is how curl_easy_pause() reads at first glance and is not what it means. Its CURLPAUSE_RECV_CONT, CURLPAUSE_SEND_CONT and CURLPAUSE_CONT are all defined as 0 — a bitmask names the directions that stay paused — so "resume just the receive side" has no spelling there at all, and the natural-looking one silently resumes both. Two booleans cannot be got backwards without saying something visibly wrong.

Two further things are easy to get wrong:

  • It may call back synchronously. libcurl hands over whatever it buffered while paused from inside curl_easy_pause(), so the stream callback (or the read callback) can run, and can pause again, before this function returns. A caller that is itself inside a callback of some other event source should defer this to its own event loop rather than call it there.
  • It must not be called after the job's completion callback has run. The easy handle is destroyed with the job immediately afterwards, and job is a dangling pointer from then on.
Parameters
jobjob whose pause state to set
recv_pausedtrue to hold the receive side paused
send_pausedtrue to hold the send side paused

Definition at line 657 of file curl.c.

660{
661 /* curl_easy_pause() takes the directions that are to REMAIN paused,
662 which is why this function does not take the ones to resume: every
663 way of naming a single direction to resume (CURLPAUSE_RECV_CONT,
664 CURLPAUSE_SEND_CONT, CURLPAUSE_CONT) is defined as 0. */
665 GNUNET_break (CURLE_OK ==
666 curl_easy_pause (job->easy_handle,
667 (recv_paused ? CURLPAUSE_RECV : 0)
668 | (send_paused ? CURLPAUSE_SEND : 0)));
669 /* Not optional: curl_multi_fdset() leaves out the socket of a
670 paused handle, so until the event loop is told to ask again it
671 will not wait on it -- and the transfer we just resumed would sit
672 there until some other job happened to wake the loop up. */
673 job->ctx->cb (job->ctx->cb_cls);
674}

References GNUNET_break, and job.

◆ GNUNET_CURL_job_add()

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.

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

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

Definition at line 753 of file curl.c.

757{
759 eh,
760 NULL,
761 jcc,
762 jcc_cls);
763}
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:678

References ctx, GNUNET_CURL_job_add2(), GNUNET_CURL_Job::jcc, and GNUNET_CURL_Job::jcc_cls.

Here is the call graph for this function:

◆ GNUNET_CURL_job_add_with_ct_json()

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.

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.

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

Definition at line 730 of file curl.c.

734{
735 struct GNUNET_CURL_Job *job;
736 struct curl_slist *job_headers = NULL;
737
738 GNUNET_assert (NULL != (job_headers =
739 curl_slist_append (NULL,
740 "Content-Type: application/json")
741 ));
743 eh,
744 job_headers,
745 jcc,
746 jcc_cls);
747 curl_slist_free_all (job_headers);
748 return job;
749}

References ctx, GNUNET_assert, GNUNET_CURL_job_add2(), and job.

Here is the call graph for this function:

◆ GNUNET_CURL_set_userpass()

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 performed with ctx.

Parameters
ctxcontext to set authentication data for
userpassstring with "$USERNAME:$PASSWORD"

Definition at line 227 of file curl.c.

229{
230 GNUNET_free (ctx->userpass);
231 if (NULL != userpass)
232 ctx->userpass = GNUNET_strdup (userpass);
233}
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.

References ctx, GNUNET_free, and GNUNET_strdup.

◆ GNUNET_CURL_set_tlscert()

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 performed with ctx.

Note that if the provided information is incorrect, the earliest operation that could fail is GNUNET_CURL_job_add() or GNUNET_CURL_job_add2()!

Parameters
ctxcontext to set authentication data for
certtypetype of the certificate
certfilefile with the certificate
keyfilefile with the private key
keypasspassphrase to decrypt keyfile (or NULL)

Definition at line 237 of file curl.c.

242{
243 GNUNET_free (ctx->certtype);
244 GNUNET_free (ctx->certfile);
245 GNUNET_free (ctx->keyfile);
246 GNUNET_free (ctx->keypass);
247 if (NULL != certtype)
248 ctx->certtype = GNUNET_strdup (certtype);
249 if (NULL != certfile)
250 ctx->certfile = GNUNET_strdup (certfile);
251 if (NULL != keyfile)
252 ctx->keyfile = GNUNET_strdup (keyfile);
253 if (NULL != keypass)
254 ctx->keypass = GNUNET_strdup (keypass);
255}

References ctx, GNUNET_free, and GNUNET_strdup.

◆ 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.

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, eh is still released!)

Definition at line 678 of file curl.c.

683{
684 struct GNUNET_CURL_Job *job;
685 struct curl_slist *all_headers;
686
687 GNUNET_assert (NULL != jcc);
688 if ( (NULL != ctx->userpass) &&
689 (0 != curl_easy_setopt (eh,
690 CURLOPT_USERPWD,
691 ctx->userpass)) )
692 return NULL;
693 if ( (NULL != ctx->certfile) &&
694 (0 != curl_easy_setopt (eh,
695 CURLOPT_SSLCERT,
696 ctx->certfile)) )
697 return NULL;
698 if ( (NULL != ctx->certtype) &&
699 (0 != curl_easy_setopt (eh,
700 CURLOPT_SSLCERTTYPE,
701 ctx->certtype)) )
702 return NULL;
703 if ( (NULL != ctx->keyfile) &&
704 (0 != curl_easy_setopt (eh,
705 CURLOPT_SSLKEY,
706 ctx->keyfile)) )
707 return NULL;
708 if ( (NULL != ctx->keypass) &&
709 (0 != curl_easy_setopt (eh,
710 CURLOPT_KEYPASSWD,
711 ctx->keypass)) )
712 return NULL;
713
714 all_headers = setup_job_headers (ctx,
715 job_headers);
716 if (NULL == (job = setup_job (eh,
717 ctx,
718 all_headers,
719 NULL)))
720 return NULL;
721
722 job->jcc = jcc;
723 job->jcc_cls = jcc_cls;
724 ctx->cb (ctx->cb_cls);
725 return job;
726}

References ctx, GNUNET_assert, job, setup_job(), and setup_job_headers().

Referenced by GNUNET_CURL_job_add(), and GNUNET_CURL_job_add_with_ct_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CURL_job_add_raw()

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.

Note that the context will make use of the CURLOPT_PRIVATE facility of the CURL eh. Used to download resources that are NOT in JSON. The raw body will be returned.

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, eh is still released!)

Definition at line 608 of file curl.c.

613{
614 struct GNUNET_CURL_Job *job;
615 struct curl_slist *all_headers;
616
617 GNUNET_assert (NULL != jcc);
618 all_headers = setup_job_headers (ctx,
619 job_headers);
620 if (NULL == (job = setup_job (eh,
621 ctx,
622 all_headers,
623 NULL)))
624 return NULL;
625 job->jcc_raw = jcc;
626 job->jcc_raw_cls = jcc_cls;
627 ctx->cb (ctx->cb_cls);
628 return job;
629}

References ctx, GNUNET_assert, job, setup_job(), and setup_job_headers().

Here is the call graph for this function:

◆ GNUNET_CURL_extend_headers()

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.

Parameters
[in,out]jobthe job to modify
extra_headersheaders to append

Definition at line 586 of file curl.c.

588{
589 struct curl_slist *all_headers = job->job_headers;
590
591 for (const struct curl_slist *curr = extra_headers;
592 NULL != curr;
593 curr = curr->next)
594 {
595 GNUNET_assert (NULL !=
596 (all_headers = curl_slist_append (all_headers,
597 curr->data)));
598 }
599 job->job_headers = all_headers;
600 GNUNET_break (CURLE_OK ==
601 curl_easy_setopt (job->easy_handle,
602 CURLOPT_HTTPHEADER,
603 all_headers));
604}

References GNUNET_assert, GNUNET_break, and job.

◆ 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 767 of file curl.c.

768{
769 struct GNUNET_CURL_Context *ctx = job->ctx;
770
772 ctx->jobs_tail,
773 job);
774 GNUNET_break (CURLM_OK ==
775 curl_multi_remove_handle (ctx->multi,
776 job->easy_handle));
777 curl_easy_cleanup (job->easy_handle);
778 GNUNET_free (job->db.buf);
779 curl_slist_free_all (job->job_headers);
780 ctx->cb (ctx->cb_cls);
782}
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.

References ctx, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, and job.

Referenced by GNUNET_CURL_perform2().

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 87 of file curl_reschedule.c.

88{
90
92 rc->ctx = ctx;
94 rc->cleaner = &clean_result;
95 return rc;
96}
static void clean_result(void *response)
Just a wrapper to avoid casting of function pointers.
Closure for GNUNET_CURL_gnunet_scheduler_reschedule().
GNUNET_CURL_RawParser parser
Parser of the raw response.
struct GNUNET_CURL_Context * ctx
Context we manage.
GNUNET_CURL_ResponseCleaner cleaner
Deallocate the response object.

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

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 59 of file curl_reschedule.c.

62{
64
66 rctx->ctx = ctx;
67 rctx->parser = rp;
68 rctx->cleaner = rc;
69
70 return rctx;
71}

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

◆ 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 100 of file curl_reschedule.c.

101{
102 if (NULL != rc->task)
104 GNUNET_free (rc);
105}
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * task
Just the task.

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

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 166 of file curl_reschedule.c.

167{
168 struct GNUNET_CURL_RescheduleContext *rc = *(void **) cls;
169
170 if (NULL != rc->task)
173 rc);
174}
static void context_task(void *cls)
Task that runs the context's event loop with the GNUnet scheduler.
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:1310

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

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 294 of file curl.c.

296{
297 ctx->async_scope_id_header = header_name;
298}

References ctx.

◆ GNUNET_CURL_is_valid_scope_id()

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.

See GNUNET_CURL_enable_async_scope_header() for the code that generates such a scope_id in an HTTP header.

Returns
GNUNET_YES iff given a valid scope ID

Definition at line 302 of file curl.c.

303{
304 if (strlen (scope_id) >= 64)
305 return GNUNET_NO;
306 for (size_t i = 0; i < strlen (scope_id); i++)
307 if (! (isalnum (scope_id[i]) || (scope_id[i] == '-')))
308 return GNUNET_NO;
309 return GNUNET_YES;
310}
@ GNUNET_YES
@ GNUNET_NO

References GNUNET_NO, and GNUNET_YES.