aboutsummaryrefslogtreecommitdiff
path: root/src/curl
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-05-10 20:08:01 +0200
committerFlorian Dold <florian.dold@gmail.com>2019-05-10 20:10:02 +0200
commitc1f06ac28fef5498952994e0399312b1fc567f22 (patch)
treead71f80bb08bfe20ff33880509263d78f334409b /src/curl
parentd1d18e6492708a0ce758ddd8c509f21b0ecbf6a0 (diff)
downloadgnunet-c1f06ac28fef5498952994e0399312b1fc567f22.tar.gz
gnunet-c1f06ac28fef5498952994e0399312b1fc567f22.zip
Implement asynchronous scope identifiers.
Without entering an asynchronous scope, logs are the same before. When entering an asynchronous scope (either thread-based of scheduler/task-based), all log lines within an asynchronous scope contain its ID. Currently this is only used in GNU Taler, for debugging requests across multiple services. This allows us to get all log lines pertaining to a particular request for a user or another service.
Diffstat (limited to 'src/curl')
-rw-r--r--src/curl/curl.c89
1 files changed, 76 insertions, 13 deletions
diff --git a/src/curl/curl.c b/src/curl/curl.c
index e13c1478f..871401c60 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -105,6 +105,18 @@ struct GNUNET_CURL_Job
105 * Buffer for response received from CURL. 105 * Buffer for response received from CURL.
106 */ 106 */
107 struct GNUNET_CURL_DownloadBuffer db; 107 struct GNUNET_CURL_DownloadBuffer db;
108
109 /**
110 * Headers used for this job, the list needs to be freed
111 * after the job has finished.
112 */
113 struct curl_slist *job_headers;
114
115 /**
116 * Header for the async scope id or NULL.
117 */
118 char *aid_header;
119
108}; 120};
109 121
110 122
@@ -134,10 +146,15 @@ struct GNUNET_CURL_Context
134 struct GNUNET_CURL_Job *jobs_tail; 146 struct GNUNET_CURL_Job *jobs_tail;
135 147
136 /** 148 /**
137 * HTTP header "application/json", created once and used 149 * Headers common for all requests in the context.
138 * for all requests that need it. 150 */
151 struct curl_slist *common_headers;
152
153 /**
154 * If non-NULL, the async scope ID is sent in a request
155 * header of this name.
139 */ 156 */
140 struct curl_slist *json_header; 157 const char *async_scope_id_header;
141 158
142 /** 159 /**
143 * Function we need to call whenever the event loop's 160 * Function we need to call whenever the event loop's
@@ -149,6 +166,7 @@ struct GNUNET_CURL_Context
149 * Closure for @e cb. 166 * Closure for @e cb.
150 */ 167 */
151 void *cb_cls; 168 void *cb_cls;
169
152}; 170};
153 171
154 172
@@ -189,14 +207,24 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
189 ctx->cb_cls = cb_cls; 207 ctx->cb_cls = cb_cls;
190 ctx->multi = multi; 208 ctx->multi = multi;
191 ctx->share = share; 209 ctx->share = share;
192 GNUNET_assert (
193 NULL != (ctx->json_header =
194 curl_slist_append (NULL, "Content-Type: application/json")));
195 return ctx; 210 return ctx;
196} 211}
197 212
198 213
199/** 214/**
215 * Enable sending the async scope ID as a header.
216 *
217 * @param ctx the context to enable this for
218 * @param header_name name of the header to send.
219 */
220void
221GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, const char *header_name)
222{
223 ctx->async_scope_id_header = header_name;
224}
225
226
227/**
200 * Callback used when downloading the reply to an HTTP request. 228 * Callback used when downloading the reply to an HTTP request.
201 * Just appends all of the data to the `buf` in the 229 * Just appends all of the data to the `buf` in the
202 * `struct DownloadBuffer` for further processing. The size of 230 * `struct DownloadBuffer` for further processing. The size of
@@ -259,16 +287,49 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
259 void *jcc_cls) 287 void *jcc_cls)
260{ 288{
261 struct GNUNET_CURL_Job *job; 289 struct GNUNET_CURL_Job *job;
290 struct curl_slist *all_headers = NULL;
291 char *aid_header = NULL;
262 292
263 if (GNUNET_YES == add_json) 293 if (GNUNET_YES == add_json)
264 if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, ctx->json_header)) 294 {
295 GNUNET_assert (
296 NULL != (all_headers =
297 curl_slist_append (NULL, "Content-Type: application/json")));
298 }
299
300 for (struct curl_slist *curr = ctx->common_headers;
301 curr != NULL;
302 curr = curr->next)
303 {
304 GNUNET_assert (
305 NULL != (all_headers =
306 curl_slist_append (all_headers, "Content-Type: application/json")));
307 }
308
309 if (NULL != ctx->async_scope_id_header)
310 {
311 struct GNUNET_AsyncScopeSave scope;
312
313 GNUNET_async_scope_get (&scope);
314 if (GNUNET_YES == scope.have_scope)
265 { 315 {
266 GNUNET_break (0); 316 aid_header = GNUNET_STRINGS_data_to_string_alloc (&scope.scope_id,
267 curl_easy_cleanup (eh); 317 sizeof (struct GNUNET_AsyncScopeId));
268 return NULL; 318 GNUNET_assert (NULL != curl_slist_append(all_headers, aid_header));
269 } 319 }
320 }
321
322 if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers))
323 {
324 GNUNET_break (0);
325 curl_easy_cleanup (eh);
326 return NULL;
327 }
270 328
271 job = GNUNET_new (struct GNUNET_CURL_Job); 329 job = GNUNET_new (struct GNUNET_CURL_Job);
330 job->job_headers = all_headers;
331 job->aid_header = aid_header;
332
272 if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) || 333 if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) ||
273 (CURLE_OK != 334 (CURLE_OK !=
274 curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) || 335 curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) ||
@@ -308,6 +369,8 @@ GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
308 curl_multi_remove_handle (ctx->multi, job->easy_handle)); 369 curl_multi_remove_handle (ctx->multi, job->easy_handle));
309 curl_easy_cleanup (job->easy_handle); 370 curl_easy_cleanup (job->easy_handle);
310 GNUNET_free_non_null (job->db.buf); 371 GNUNET_free_non_null (job->db.buf);
372 GNUNET_free_non_null (job->aid_header);
373 curl_slist_free_all (job->job_headers);
311 GNUNET_free (job); 374 GNUNET_free (job);
312} 375}
313 376
@@ -401,8 +464,8 @@ download_get_result (struct GNUNET_CURL_DownloadBuffer *db,
401int 464int
402GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) 465GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header)
403{ 466{
404 ctx->json_header = curl_slist_append (ctx->json_header, header); 467 ctx->common_headers = curl_slist_append (ctx->common_headers, header);
405 if (NULL == ctx->json_header) 468 if (NULL == ctx->common_headers)
406 return GNUNET_SYSERR; 469 return GNUNET_SYSERR;
407 470
408 return GNUNET_OK; 471 return GNUNET_OK;
@@ -599,7 +662,7 @@ GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
599 GNUNET_assert (NULL == ctx->jobs_head); 662 GNUNET_assert (NULL == ctx->jobs_head);
600 curl_share_cleanup (ctx->share); 663 curl_share_cleanup (ctx->share);
601 curl_multi_cleanup (ctx->multi); 664 curl_multi_cleanup (ctx->multi);
602 curl_slist_free_all (ctx->json_header); 665 curl_slist_free_all (ctx->common_headers);
603 GNUNET_free (ctx); 666 GNUNET_free (ctx);
604} 667}
605 668