aboutsummaryrefslogtreecommitdiff
path: root/src/curl/curl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/curl/curl.c')
-rw-r--r--src/curl/curl.c529
1 files changed, 263 insertions, 266 deletions
diff --git a/src/curl/curl.c b/src/curl/curl.c
index 38a1f5fcd..8e66ba4cb 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -1,22 +1,22 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016, 2018 GNUnet e.V. 3 Copyright (C) 2014, 2015, 2016, 2018 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 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, 7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 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/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20/** 20/**
21 * @file curl/curl.c 21 * @file curl/curl.c
22 * @brief API for downloading JSON via CURL 22 * @brief API for downloading JSON via CURL
@@ -40,23 +40,23 @@
40 * @param code what was the curl error code 40 * @param code what was the curl error code
41 */ 41 */
42#define CURL_STRERROR(type, function, code) \ 42#define CURL_STRERROR(type, function, code) \
43 GNUNET_log (type, \ 43 GNUNET_log(type, \
44 "Curl function `%s' has failed at `%s:%d' with error: %s\n", \ 44 "Curl function `%s' has failed at `%s:%d' with error: %s\n", \
45 function, \ 45 function, \
46 __FILE__, \ 46 __FILE__, \
47 __LINE__, \ 47 __LINE__, \
48 curl_easy_strerror (code)); 48 curl_easy_strerror(code));
49 49
50/** 50/**
51 * Print JSON parsing related error information 51 * Print JSON parsing related error information
52 */ 52 */
53#define JSON_WARN(error) \ 53#define JSON_WARN(error) \
54 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \ 54 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, \
55 "JSON parsing failed at %s:%u: %s (%s)\n", \ 55 "JSON parsing failed at %s:%u: %s (%s)\n", \
56 __FILE__, \ 56 __FILE__, \
57 __LINE__, \ 57 __LINE__, \
58 error.text, \ 58 error.text, \
59 error.source) 59 error.source)
60 60
61 61
62/** 62/**
@@ -68,9 +68,7 @@ static int curl_fail;
68/** 68/**
69 * Jobs are CURL requests running within a `struct GNUNET_CURL_Context`. 69 * Jobs are CURL requests running within a `struct GNUNET_CURL_Context`.
70 */ 70 */
71struct GNUNET_CURL_Job 71struct GNUNET_CURL_Job {
72{
73
74 /** 72 /**
75 * We keep jobs in a DLL. 73 * We keep jobs in a DLL.
76 */ 74 */
@@ -117,8 +115,7 @@ struct GNUNET_CURL_Job
117/** 115/**
118 * Context 116 * Context
119 */ 117 */
120struct GNUNET_CURL_Context 118struct GNUNET_CURL_Context {
121{
122 /** 119 /**
123 * Curl multi handle 120 * Curl multi handle
124 */ 121 */
@@ -172,30 +169,30 @@ struct GNUNET_CURL_Context
172 * @return library context 169 * @return library context
173 */ 170 */
174struct GNUNET_CURL_Context * 171struct GNUNET_CURL_Context *
175GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls) 172GNUNET_CURL_init(GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
176{ 173{
177 struct GNUNET_CURL_Context *ctx; 174 struct GNUNET_CURL_Context *ctx;
178 CURLM *multi; 175 CURLM *multi;
179 CURLSH *share; 176 CURLSH *share;
180 177
181 if (curl_fail) 178 if (curl_fail)
182 { 179 {
183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Curl was not initialised properly\n"); 180 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Curl was not initialised properly\n");
184 return NULL; 181 return NULL;
185 } 182 }
186 if (NULL == (multi = curl_multi_init ())) 183 if (NULL == (multi = curl_multi_init()))
187 { 184 {
188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 185 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
189 "Failed to create a Curl multi handle\n"); 186 "Failed to create a Curl multi handle\n");
190 return NULL; 187 return NULL;
191 } 188 }
192 if (NULL == (share = curl_share_init ())) 189 if (NULL == (share = curl_share_init()))
193 { 190 {
194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 191 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
195 "Failed to create a Curl share handle\n"); 192 "Failed to create a Curl share handle\n");
196 return NULL; 193 return NULL;
197 } 194 }
198 ctx = GNUNET_new (struct GNUNET_CURL_Context); 195 ctx = GNUNET_new(struct GNUNET_CURL_Context);
199 ctx->cb = cb; 196 ctx->cb = cb;
200 ctx->cb_cls = cb_cls; 197 ctx->cb_cls = cb_cls;
201 ctx->multi = multi; 198 ctx->multi = multi;
@@ -211,8 +208,8 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
211 * @param header_name name of the header to send. 208 * @param header_name name of the header to send.
212 */ 209 */
213void 210void
214GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, 211GNUNET_CURL_enable_async_scope_header(struct GNUNET_CURL_Context *ctx,
215 const char *header_name) 212 const char *header_name)
216{ 213{
217 ctx->async_scope_id_header = header_name; 214 ctx->async_scope_id_header = header_name;
218} 215}
@@ -232,26 +229,26 @@ GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx,
232 * @return number of bytes processed from @a bufptr 229 * @return number of bytes processed from @a bufptr
233 */ 230 */
234static size_t 231static size_t
235download_cb (char *bufptr, size_t size, size_t nitems, void *cls) 232download_cb(char *bufptr, size_t size, size_t nitems, void *cls)
236{ 233{
237 struct GNUNET_CURL_DownloadBuffer *db = cls; 234 struct GNUNET_CURL_DownloadBuffer *db = cls;
238 size_t msize; 235 size_t msize;
239 void *buf; 236 void *buf;
240 237
241 if (0 == size * nitems) 238 if (0 == size * nitems)
242 { 239 {
243 /* Nothing (left) to do */ 240 /* Nothing (left) to do */
244 return 0; 241 return 0;
245 } 242 }
246 msize = size * nitems; 243 msize = size * nitems;
247 if ((msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED) 244 if ((msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
248 { 245 {
249 db->eno = ENOMEM; 246 db->eno = ENOMEM;
250 return 0; /* signals an error to curl */ 247 return 0; /* signals an error to curl */
251 } 248 }
252 db->buf = GNUNET_realloc (db->buf, db->buf_size + msize); 249 db->buf = GNUNET_realloc(db->buf, db->buf_size + msize);
253 buf = db->buf + db->buf_size; 250 buf = db->buf + db->buf_size;
254 GNUNET_memcpy (buf, bufptr, msize); 251 GNUNET_memcpy(buf, bufptr, msize);
255 db->buf_size += msize; 252 db->buf_size += msize;
256 return msize; 253 return msize;
257} 254}
@@ -277,77 +274,77 @@ download_cb (char *bufptr, size_t size, size_t nitems, void *cls)
277 * @return NULL on error (in this case, @eh is still released!) 274 * @return NULL on error (in this case, @eh is still released!)
278 */ 275 */
279struct GNUNET_CURL_Job * 276struct GNUNET_CURL_Job *
280GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, 277GNUNET_CURL_job_add2(struct GNUNET_CURL_Context *ctx,
281 CURL *eh, 278 CURL *eh,
282 const struct curl_slist *job_headers, 279 const struct curl_slist *job_headers,
283 GNUNET_CURL_JobCompletionCallback jcc, 280 GNUNET_CURL_JobCompletionCallback jcc,
284 void *jcc_cls) 281 void *jcc_cls)
285{ 282{
286 struct GNUNET_CURL_Job *job; 283 struct GNUNET_CURL_Job *job;
287 struct curl_slist *all_headers = NULL; 284 struct curl_slist *all_headers = NULL;
288 285
289 for (const struct curl_slist *curr = job_headers; curr != NULL; 286 for (const struct curl_slist *curr = job_headers; curr != NULL;
290 curr = curr->next) 287 curr = curr->next)
291 { 288 {
292 GNUNET_assert (NULL != 289 GNUNET_assert(NULL !=
293 (all_headers = curl_slist_append (all_headers, curr->data))); 290 (all_headers = curl_slist_append(all_headers, curr->data)));
294 } 291 }
295 292
296 for (const struct curl_slist *curr = ctx->common_headers; curr != NULL; 293 for (const struct curl_slist *curr = ctx->common_headers; curr != NULL;
297 curr = curr->next) 294 curr = curr->next)
298 { 295 {
299 GNUNET_assert (NULL != 296 GNUNET_assert(NULL !=
300 (all_headers = curl_slist_append (all_headers, curr->data))); 297 (all_headers = curl_slist_append(all_headers, curr->data)));
301 } 298 }
302 299
303 if (NULL != ctx->async_scope_id_header) 300 if (NULL != ctx->async_scope_id_header)
304 {
305 struct GNUNET_AsyncScopeSave scope;
306
307 GNUNET_async_scope_get (&scope);
308 if (GNUNET_YES == scope.have_scope)
309 { 301 {
310 char *aid_header = NULL; 302 struct GNUNET_AsyncScopeSave scope;
311 aid_header = 303
312 GNUNET_STRINGS_data_to_string_alloc (&scope.scope_id, 304 GNUNET_async_scope_get(&scope);
313 sizeof ( 305 if (GNUNET_YES == scope.have_scope)
314 struct GNUNET_AsyncScopeId)); 306 {
315 GNUNET_assert (NULL != aid_header); 307 char *aid_header = NULL;
316 GNUNET_assert (NULL != curl_slist_append (all_headers, aid_header)); 308 aid_header =
317 GNUNET_free (aid_header); 309 GNUNET_STRINGS_data_to_string_alloc(&scope.scope_id,
310 sizeof(
311 struct GNUNET_AsyncScopeId));
312 GNUNET_assert(NULL != aid_header);
313 GNUNET_assert(NULL != curl_slist_append(all_headers, aid_header));
314 GNUNET_free(aid_header);
315 }
318 } 316 }
319 }
320 317
321 if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers)) 318 if (CURLE_OK != curl_easy_setopt(eh, CURLOPT_HTTPHEADER, all_headers))
322 { 319 {
323 GNUNET_break (0); 320 GNUNET_break(0);
324 curl_slist_free_all (all_headers); 321 curl_slist_free_all(all_headers);
325 curl_easy_cleanup (eh); 322 curl_easy_cleanup(eh);
326 return NULL; 323 return NULL;
327 } 324 }
328 325
329 job = GNUNET_new (struct GNUNET_CURL_Job); 326 job = GNUNET_new(struct GNUNET_CURL_Job);
330 job->job_headers = all_headers; 327 job->job_headers = all_headers;
331 328
332 if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) || 329 if ((CURLE_OK != curl_easy_setopt(eh, CURLOPT_PRIVATE, job)) ||
333 (CURLE_OK != 330 (CURLE_OK !=
334 curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) || 331 curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, &download_cb)) ||
335 (CURLE_OK != curl_easy_setopt (eh, CURLOPT_WRITEDATA, &job->db)) || 332 (CURLE_OK != curl_easy_setopt(eh, CURLOPT_WRITEDATA, &job->db)) ||
336 (CURLE_OK != curl_easy_setopt (eh, CURLOPT_SHARE, ctx->share)) || 333 (CURLE_OK != curl_easy_setopt(eh, CURLOPT_SHARE, ctx->share)) ||
337 (CURLM_OK != curl_multi_add_handle (ctx->multi, eh))) 334 (CURLM_OK != curl_multi_add_handle(ctx->multi, eh)))
338 { 335 {
339 GNUNET_break (0); 336 GNUNET_break(0);
340 GNUNET_free (job); 337 GNUNET_free(job);
341 curl_easy_cleanup (eh); 338 curl_easy_cleanup(eh);
342 return NULL; 339 return NULL;
343 } 340 }
344 341
345 job->easy_handle = eh; 342 job->easy_handle = eh;
346 job->ctx = ctx; 343 job->ctx = ctx;
347 job->jcc = jcc; 344 job->jcc = jcc;
348 job->jcc_cls = jcc_cls; 345 job->jcc_cls = jcc_cls;
349 GNUNET_CONTAINER_DLL_insert (ctx->jobs_head, ctx->jobs_tail, job); 346 GNUNET_CONTAINER_DLL_insert(ctx->jobs_head, ctx->jobs_tail, job);
350 ctx->cb (ctx->cb_cls); 347 ctx->cb(ctx->cb_cls);
351 return job; 348 return job;
352} 349}
353 350
@@ -369,24 +366,24 @@ GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx,
369 * @return NULL on error (in this case, @eh is still released!) 366 * @return NULL on error (in this case, @eh is still released!)
370 */ 367 */
371struct GNUNET_CURL_Job * 368struct GNUNET_CURL_Job *
372GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, 369GNUNET_CURL_job_add(struct GNUNET_CURL_Context *ctx,
373 CURL *eh, 370 CURL *eh,
374 int add_json, 371 int add_json,
375 GNUNET_CURL_JobCompletionCallback jcc, 372 GNUNET_CURL_JobCompletionCallback jcc,
376 void *jcc_cls) 373 void *jcc_cls)
377{ 374{
378 struct GNUNET_CURL_Job *job; 375 struct GNUNET_CURL_Job *job;
379 struct curl_slist *job_headers = NULL; 376 struct curl_slist *job_headers = NULL;
380 377
381 if (GNUNET_YES == add_json) 378 if (GNUNET_YES == add_json)
382 { 379 {
383 GNUNET_assert ( 380 GNUNET_assert(
384 NULL != (job_headers = 381 NULL != (job_headers =
385 curl_slist_append (NULL, "Content-Type: application/json"))); 382 curl_slist_append(NULL, "Content-Type: application/json")));
386 } 383 }
387 384
388 job = GNUNET_CURL_job_add2 (ctx, eh, job_headers, jcc, jcc_cls); 385 job = GNUNET_CURL_job_add2(ctx, eh, job_headers, jcc, jcc_cls);
389 curl_slist_free_all (job_headers); 386 curl_slist_free_all(job_headers);
390 return job; 387 return job;
391} 388}
392 389
@@ -398,17 +395,17 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
398 * @param job job to cancel 395 * @param job job to cancel
399 */ 396 */
400void 397void
401GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job) 398GNUNET_CURL_job_cancel(struct GNUNET_CURL_Job *job)
402{ 399{
403 struct GNUNET_CURL_Context *ctx = job->ctx; 400 struct GNUNET_CURL_Context *ctx = job->ctx;
404 401
405 GNUNET_CONTAINER_DLL_remove (ctx->jobs_head, ctx->jobs_tail, job); 402 GNUNET_CONTAINER_DLL_remove(ctx->jobs_head, ctx->jobs_tail, job);
406 GNUNET_break (CURLM_OK == 403 GNUNET_break(CURLM_OK ==
407 curl_multi_remove_handle (ctx->multi, job->easy_handle)); 404 curl_multi_remove_handle(ctx->multi, job->easy_handle));
408 curl_easy_cleanup (job->easy_handle); 405 curl_easy_cleanup(job->easy_handle);
409 GNUNET_free_non_null (job->db.buf); 406 GNUNET_free_non_null(job->db.buf);
410 curl_slist_free_all (job->job_headers); 407 curl_slist_free_all(job->job_headers);
411 GNUNET_free (job); 408 GNUNET_free(job);
412} 409}
413 410
414 411
@@ -431,62 +428,62 @@ GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
431 * @return NULL if downloading a JSON reply failed. 428 * @return NULL if downloading a JSON reply failed.
432 */ 429 */
433void * 430void *
434GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db, 431GNUNET_CURL_download_get_result_(struct GNUNET_CURL_DownloadBuffer *db,
435 CURL *eh, 432 CURL *eh,
436 long *response_code) 433 long *response_code)
437{ 434{
438 json_t *json; 435 json_t *json;
439 json_error_t error; 436 json_error_t error;
440 char *ct; 437 char *ct;
441 438
442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 439 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
443 "Downloaded body: %.*s\n", 440 "Downloaded body: %.*s\n",
444 (int) db->buf_size, 441 (int)db->buf_size,
445 (char *) db->buf); 442 (char *)db->buf);
446 443
447 if ((CURLE_OK != curl_easy_getinfo (eh, CURLINFO_CONTENT_TYPE, &ct)) || 444 if ((CURLE_OK != curl_easy_getinfo(eh, CURLINFO_CONTENT_TYPE, &ct)) ||
448 (NULL == ct) || (0 != strcasecmp (ct, "application/json"))) 445 (NULL == ct) || (0 != strcasecmp(ct, "application/json")))
449 {
450 /* No content type or explicitly not JSON, refuse to parse
451 (but keep response code) */
452 if (CURLE_OK !=
453 curl_easy_getinfo (eh, CURLINFO_RESPONSE_CODE, response_code))
454 { 446 {
455 /* unexpected error... */ 447 /* No content type or explicitly not JSON, refuse to parse
456 GNUNET_break (0); 448 (but keep response code) */
457 *response_code = 0; 449 if (CURLE_OK !=
450 curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, response_code))
451 {
452 /* unexpected error... */
453 GNUNET_break(0);
454 *response_code = 0;
455 }
456 if (0 != db->buf_size)
457 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
458 "Did NOT detect response as JSON\n");
459 return NULL;
458 } 460 }
459 if (0 != db->buf_size)
460 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
461 "Did NOT detect response as JSON\n");
462 return NULL;
463 }
464 json = NULL; 461 json = NULL;
465 if (0 == db->eno) 462 if (0 == db->eno)
466 {
467 json = json_loadb (db->buf,
468 db->buf_size,
469 JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
470 &error);
471 if (NULL == json)
472 { 463 {
473 JSON_WARN (error); 464 json = json_loadb(db->buf,
474 *response_code = 0; 465 db->buf_size,
466 JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
467 &error);
468 if (NULL == json)
469 {
470 JSON_WARN(error);
471 *response_code = 0;
472 }
475 } 473 }
476 } 474 GNUNET_free_non_null(db->buf);
477 GNUNET_free_non_null (db->buf);
478 db->buf = NULL; 475 db->buf = NULL;
479 db->buf_size = 0; 476 db->buf_size = 0;
480 if (NULL != json) 477 if (NULL != json)
481 {
482 if (CURLE_OK !=
483 curl_easy_getinfo (eh, CURLINFO_RESPONSE_CODE, response_code))
484 { 478 {
485 /* unexpected error... */ 479 if (CURLE_OK !=
486 GNUNET_break (0); 480 curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, response_code))
487 *response_code = 0; 481 {
482 /* unexpected error... */
483 GNUNET_break(0);
484 *response_code = 0;
485 }
488 } 486 }
489 }
490 return json; 487 return json;
491} 488}
492 489
@@ -499,9 +496,9 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
499 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. 496 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise.
500 */ 497 */
501int 498int
502GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) 499GNUNET_CURL_append_header(struct GNUNET_CURL_Context *ctx, const char *header)
503{ 500{
504 ctx->common_headers = curl_slist_append (ctx->common_headers, header); 501 ctx->common_headers = curl_slist_append(ctx->common_headers, header);
505 if (NULL == ctx->common_headers) 502 if (NULL == ctx->common_headers)
506 return GNUNET_SYSERR; 503 return GNUNET_SYSERR;
507 504
@@ -518,98 +515,98 @@ GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header)
518 * @param rc cleans/frees the response 515 * @param rc cleans/frees the response
519 */ 516 */
520void 517void
521GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, 518GNUNET_CURL_perform2(struct GNUNET_CURL_Context *ctx,
522 GNUNET_CURL_RawParser rp, 519 GNUNET_CURL_RawParser rp,
523 GNUNET_CURL_ResponseCleaner rc) 520 GNUNET_CURL_ResponseCleaner rc)
524{ 521{
525 CURLMsg *cmsg; 522 CURLMsg *cmsg;
526 int n_running; 523 int n_running;
527 int n_completed; 524 int n_completed;
528 525
529 (void) curl_multi_perform (ctx->multi, &n_running); 526 (void)curl_multi_perform(ctx->multi, &n_running);
530 while (NULL != (cmsg = curl_multi_info_read (ctx->multi, &n_completed))) 527 while (NULL != (cmsg = curl_multi_info_read(ctx->multi, &n_completed)))
531 { 528 {
532 struct GNUNET_CURL_Job *job; 529 struct GNUNET_CURL_Job *job;
533 long response_code; 530 long response_code;
534 void *response; 531 void *response;
535 532
536 /* Only documented return value is CURLMSG_DONE */ 533 /* Only documented return value is CURLMSG_DONE */
537 GNUNET_break (CURLMSG_DONE == cmsg->msg); 534 GNUNET_break(CURLMSG_DONE == cmsg->msg);
538 GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 535 GNUNET_assert(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
539 CURLINFO_PRIVATE, 536 CURLINFO_PRIVATE,
540 (char **) &job)); 537 (char **)&job));
541 GNUNET_assert (job->ctx == ctx); 538 GNUNET_assert(job->ctx == ctx);
542 response_code = 0; 539 response_code = 0;
543 response = rp (&job->db, job->easy_handle, &response_code); 540 response = rp(&job->db, job->easy_handle, &response_code);
544#if ENABLE_BENCHMARK 541#if ENABLE_BENCHMARK
545 { 542 {
546 char *url = NULL; 543 char *url = NULL;
547 double total_as_double = 0; 544 double total_as_double = 0;
548 struct GNUNET_TIME_Relative total; 545 struct GNUNET_TIME_Relative total;
549 struct UrlRequestData *urd; 546 struct UrlRequestData *urd;
550 /* Some care required, as curl is using data types (long vs curl_off_t vs 547 /* Some care required, as curl is using data types (long vs curl_off_t vs
551 * double) inconsistently to store byte count. */ 548 * double) inconsistently to store byte count. */
552 curl_off_t size_curl = 0; 549 curl_off_t size_curl = 0;
553 long size_long = 0; 550 long size_long = 0;
554 uint64_t bytes_sent = 0; 551 uint64_t bytes_sent = 0;
555 uint64_t bytes_received = 0; 552 uint64_t bytes_received = 0;
556 553
557 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 554 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
558 CURLINFO_TOTAL_TIME, 555 CURLINFO_TOTAL_TIME,
559 &total_as_double)); 556 &total_as_double));
560 total.rel_value_us = total_as_double * 1000 * 1000; 557 total.rel_value_us = total_as_double * 1000 * 1000;
561 558
562 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 559 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
563 CURLINFO_EFFECTIVE_URL, 560 CURLINFO_EFFECTIVE_URL,
564 &url)); 561 &url));
565 562
566 /* HEADER_SIZE + SIZE_DOWNLOAD_T is hopefully the total 563 /* HEADER_SIZE + SIZE_DOWNLOAD_T is hopefully the total
567 number of bytes received, not clear from curl docs. */ 564 number of bytes received, not clear from curl docs. */
568 565
569 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 566 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
570 CURLINFO_HEADER_SIZE, 567 CURLINFO_HEADER_SIZE,
571 &size_long)); 568 &size_long));
572 bytes_received += size_long; 569 bytes_received += size_long;
573 570
574 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 571 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
575 CURLINFO_SIZE_DOWNLOAD_T, 572 CURLINFO_SIZE_DOWNLOAD_T,
576 &size_curl)); 573 &size_curl));
577 bytes_received += size_curl; 574 bytes_received += size_curl;
578 575
579 /* REQUEST_SIZE + SIZE_UPLOAD_T is hopefully the total number of bytes 576 /* REQUEST_SIZE + SIZE_UPLOAD_T is hopefully the total number of bytes
580 sent, again docs are not completely clear. */ 577 sent, again docs are not completely clear. */
581 578
582 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 579 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
583 CURLINFO_REQUEST_SIZE, 580 CURLINFO_REQUEST_SIZE,
584 &size_long)); 581 &size_long));
585 bytes_sent += size_long; 582 bytes_sent += size_long;
586 583
587 /* We obtain this value to check an invariant, but never use it otherwise. */ 584 /* We obtain this value to check an invariant, but never use it otherwise. */
588 GNUNET_break (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 585 GNUNET_break(CURLE_OK == curl_easy_getinfo(cmsg->easy_handle,
589 CURLINFO_SIZE_UPLOAD_T, 586 CURLINFO_SIZE_UPLOAD_T,
590 &size_curl)); 587 &size_curl));
591 588
592 /* CURLINFO_SIZE_UPLOAD_T <= CURLINFO_REQUEST_SIZE should 589 /* CURLINFO_SIZE_UPLOAD_T <= CURLINFO_REQUEST_SIZE should
593 be an invariant. 590 be an invariant.
594 As verified with 591 As verified with
595 curl -w "foo%{size_request} -XPOST --data "ABC" $URL 592 curl -w "foo%{size_request} -XPOST --data "ABC" $URL
596 the CURLINFO_REQUEST_SIZE should be the whole size of the request 593 the CURLINFO_REQUEST_SIZE should be the whole size of the request
597 including headers and body. 594 including headers and body.
598 */ 595 */
599 GNUNET_break (size_curl <= size_long); 596 GNUNET_break(size_curl <= size_long);
600 597
601 urd = get_url_benchmark_data (url, (unsigned int) response_code); 598 urd = get_url_benchmark_data(url, (unsigned int)response_code);
602 urd->count++; 599 urd->count++;
603 urd->time = GNUNET_TIME_relative_add (urd->time, total); 600 urd->time = GNUNET_TIME_relative_add(urd->time, total);
604 urd->time_max = GNUNET_TIME_relative_max (total, urd->time_max); 601 urd->time_max = GNUNET_TIME_relative_max(total, urd->time_max);
605 urd->bytes_sent += bytes_sent; 602 urd->bytes_sent += bytes_sent;
606 urd->bytes_received += bytes_received; 603 urd->bytes_received += bytes_received;
607 } 604 }
608#endif 605#endif
609 job->jcc (job->jcc_cls, response_code, response); 606 job->jcc(job->jcc_cls, response_code, response);
610 rc (response); 607 rc(response);
611 GNUNET_CURL_job_cancel (job); 608 GNUNET_CURL_job_cancel(job);
612 } 609 }
613} 610}
614 611
615 612
@@ -619,11 +616,11 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
619 * @param ctx the library context 616 * @param ctx the library context
620 */ 617 */
621void 618void
622GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) 619GNUNET_CURL_perform(struct GNUNET_CURL_Context *ctx)
623{ 620{
624 GNUNET_CURL_perform2 (ctx, 621 GNUNET_CURL_perform2(ctx,
625 &GNUNET_CURL_download_get_result_, 622 &GNUNET_CURL_download_get_result_,
626 (GNUNET_CURL_ResponseCleaner) &json_decref); 623 (GNUNET_CURL_ResponseCleaner) & json_decref);
627} 624}
628 625
629 626
@@ -656,25 +653,25 @@ GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
656 * proceed immediately with #GNUNET_CURL_perform(). 653 * proceed immediately with #GNUNET_CURL_perform().
657 */ 654 */
658void 655void
659GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, 656GNUNET_CURL_get_select_info(struct GNUNET_CURL_Context *ctx,
660 fd_set *read_fd_set, 657 fd_set *read_fd_set,
661 fd_set *write_fd_set, 658 fd_set *write_fd_set,
662 fd_set *except_fd_set, 659 fd_set *except_fd_set,
663 int *max_fd, 660 int *max_fd,
664 long *timeout) 661 long *timeout)
665{ 662{
666 long to; 663 long to;
667 int m; 664 int m;
668 665
669 m = -1; 666 m = -1;
670 GNUNET_assert (CURLM_OK == curl_multi_fdset (ctx->multi, 667 GNUNET_assert(CURLM_OK == curl_multi_fdset(ctx->multi,
671 read_fd_set, 668 read_fd_set,
672 write_fd_set, 669 write_fd_set,
673 except_fd_set, 670 except_fd_set,
674 &m)); 671 &m));
675 to = *timeout; 672 to = *timeout;
676 *max_fd = GNUNET_MAX (m, *max_fd); 673 *max_fd = GNUNET_MAX(m, *max_fd);
677 GNUNET_assert (CURLM_OK == curl_multi_timeout (ctx->multi, &to)); 674 GNUNET_assert(CURLM_OK == curl_multi_timeout(ctx->multi, &to));
678 675
679 /* Only if what we got back from curl is smaller than what we 676 /* Only if what we got back from curl is smaller than what we
680 already had (-1 == infinity!), then update timeout */ 677 already had (-1 == infinity!), then update timeout */
@@ -693,14 +690,14 @@ GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx,
693 * @param ctx the library context 690 * @param ctx the library context
694 */ 691 */
695void 692void
696GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx) 693GNUNET_CURL_fini(struct GNUNET_CURL_Context *ctx)
697{ 694{
698 /* all jobs must have been cancelled at this time, assert this */ 695 /* all jobs must have been cancelled at this time, assert this */
699 GNUNET_assert (NULL == ctx->jobs_head); 696 GNUNET_assert(NULL == ctx->jobs_head);
700 curl_share_cleanup (ctx->share); 697 curl_share_cleanup(ctx->share);
701 curl_multi_cleanup (ctx->multi); 698 curl_multi_cleanup(ctx->multi);
702 curl_slist_free_all (ctx->common_headers); 699 curl_slist_free_all(ctx->common_headers);
703 GNUNET_free (ctx); 700 GNUNET_free(ctx);
704} 701}
705 702
706 703
@@ -708,15 +705,15 @@ GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx)
708 * Initial global setup logic, specifically runs the Curl setup. 705 * Initial global setup logic, specifically runs the Curl setup.
709 */ 706 */
710__attribute__ ((constructor)) void 707__attribute__ ((constructor)) void
711GNUNET_CURL_constructor__ (void) 708GNUNET_CURL_constructor__(void)
712{ 709{
713 CURLcode ret; 710 CURLcode ret;
714 711
715 if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT))) 712 if (CURLE_OK != (ret = curl_global_init(CURL_GLOBAL_DEFAULT)))
716 { 713 {
717 CURL_STRERROR (GNUNET_ERROR_TYPE_ERROR, "curl_global_init", ret); 714 CURL_STRERROR(GNUNET_ERROR_TYPE_ERROR, "curl_global_init", ret);
718 curl_fail = 1; 715 curl_fail = 1;
719 } 716 }
720} 717}
721 718
722 719
@@ -724,11 +721,11 @@ GNUNET_CURL_constructor__ (void)
724 * Cleans up after us, specifically runs the Curl cleanup. 721 * Cleans up after us, specifically runs the Curl cleanup.
725 */ 722 */
726__attribute__ ((destructor)) void 723__attribute__ ((destructor)) void
727GNUNET_CURL_destructor__ (void) 724GNUNET_CURL_destructor__(void)
728{ 725{
729 if (curl_fail) 726 if (curl_fail)
730 return; 727 return;
731 curl_global_cleanup (); 728 curl_global_cleanup();
732} 729}
733 730
734/* end of curl.c */ 731/* end of curl.c */