diff options
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 114 |
1 files changed, 47 insertions, 67 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 79f70bb6c..179c9580e 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2002--2012 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -55,10 +55,10 @@ client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) | |||
55 | } | 55 | } |
56 | #if BUILD_HTTPS | 56 | #if BUILD_HTTPS |
57 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https", | 57 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https", |
58 | "Client: %X - %s", cls, text); | 58 | "Client: %p - %s", cls, text); |
59 | #else | 59 | #else |
60 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http", | 60 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http", |
61 | "Client: %X - %s", cls, text); | 61 | "Client: %p - %s", cls, text); |
62 | #endif | 62 | #endif |
63 | } | 63 | } |
64 | return 0; | 64 | return 0; |
@@ -73,6 +73,7 @@ client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) | |||
73 | static void | 73 | static void |
74 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 74 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
75 | 75 | ||
76 | |||
76 | /** | 77 | /** |
77 | * Function setting up file descriptors and scheduling task to run | 78 | * Function setting up file descriptors and scheduling task to run |
78 | * | 79 | * |
@@ -99,7 +100,6 @@ client_schedule (struct Plugin *plugin, int now) | |||
99 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | 100 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); |
100 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | 101 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; |
101 | } | 102 | } |
102 | |||
103 | max = -1; | 103 | max = -1; |
104 | FD_ZERO (&rs); | 104 | FD_ZERO (&rs); |
105 | FD_ZERO (&ws); | 105 | FD_ZERO (&ws); |
@@ -154,24 +154,22 @@ client_send (struct Session *s, struct HTTP_Message *msg) | |||
154 | GNUNET_break (0); | 154 | GNUNET_break (0); |
155 | return GNUNET_SYSERR; | 155 | return GNUNET_SYSERR; |
156 | } | 156 | } |
157 | |||
158 | if (s->client_put_paused == GNUNET_YES) | 157 | if (s->client_put_paused == GNUNET_YES) |
159 | { | 158 | { |
160 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | 159 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, |
161 | "Client: %X was suspended, unpausing\n", s->client_put); | 160 | "Client: %p was suspended, unpausing\n", s->client_put); |
162 | s->client_put_paused = GNUNET_NO; | 161 | s->client_put_paused = GNUNET_NO; |
163 | curl_easy_pause (s->client_put, CURLPAUSE_CONT); | 162 | curl_easy_pause (s->client_put, CURLPAUSE_CONT); |
164 | } | 163 | } |
165 | |||
166 | client_schedule (s->plugin, GNUNET_YES); | 164 | client_schedule (s->plugin, GNUNET_YES); |
167 | 165 | ||
168 | return GNUNET_OK; | 166 | return GNUNET_OK; |
169 | } | 167 | } |
170 | 168 | ||
171 | 169 | ||
172 | |||
173 | /** | 170 | /** |
174 | * Task performing curl operations | 171 | * Task performing curl operations |
172 | * | ||
175 | * @param cls plugin as closure | 173 | * @param cls plugin as closure |
176 | * @param tc gnunet scheduler task context | 174 | * @param tc gnunet scheduler task context |
177 | */ | 175 | */ |
@@ -228,7 +226,7 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
228 | if (msg->msg == CURLMSG_DONE) | 226 | if (msg->msg == CURLMSG_DONE) |
229 | { | 227 | { |
230 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 228 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
231 | "Client: %X connection to '%s' %s ended with reason %i: `%s'\n", | 229 | "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", |
232 | msg->easy_handle, GNUNET_i2s (&s->target), | 230 | msg->easy_handle, GNUNET_i2s (&s->target), |
233 | http_plugin_address_to_string (NULL, s->addr, | 231 | http_plugin_address_to_string (NULL, s->addr, |
234 | s->addrlen), | 232 | s->addrlen), |
@@ -236,7 +234,11 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
236 | curl_easy_strerror (msg->data.result)); | 234 | curl_easy_strerror (msg->data.result)); |
237 | 235 | ||
238 | client_disconnect (s); | 236 | client_disconnect (s); |
239 | //GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,"Notifying about ended session to peer `%s' `%s'\n", GNUNET_i2s (&s->target), http_plugin_address_to_string (plugin, s->addr, s->addrlen)); | 237 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
238 | plugin->name, | ||
239 | "Notifying about ended session to peer `%s' `%s'\n", | ||
240 | GNUNET_i2s (&s->target), | ||
241 | http_plugin_address_to_string (plugin, s->addr, s->addrlen)); | ||
240 | notify_session_end (plugin, &s->target, s); | 242 | notify_session_end (plugin, &s->target, s); |
241 | } | 243 | } |
242 | } | 244 | } |
@@ -245,6 +247,7 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
245 | client_schedule (plugin, GNUNET_NO); | 247 | client_schedule (plugin, GNUNET_NO); |
246 | } | 248 | } |
247 | 249 | ||
250 | |||
248 | int | 251 | int |
249 | client_disconnect (struct Session *s) | 252 | client_disconnect (struct Session *s) |
250 | { | 253 | { |
@@ -263,7 +266,7 @@ client_disconnect (struct Session *s) | |||
263 | if (s->client_put != NULL) | 266 | if (s->client_put != NULL) |
264 | { | 267 | { |
265 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 268 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
266 | "Client: %X Deleting outbound PUT session to peer `%s'\n", | 269 | "Client: %p Deleting outbound PUT session to peer `%s'\n", |
267 | s->client_put, GNUNET_i2s (&s->target)); | 270 | s->client_put, GNUNET_i2s (&s->target)); |
268 | 271 | ||
269 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); | 272 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); |
@@ -287,7 +290,7 @@ client_disconnect (struct Session *s) | |||
287 | if (s->client_get != NULL) | 290 | if (s->client_get != NULL) |
288 | { | 291 | { |
289 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 292 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
290 | "Client: %X Deleting outbound GET session to peer `%s'\n", | 293 | "Client: %p Deleting outbound GET session to peer `%s'\n", |
291 | s->client_get, GNUNET_i2s (&s->target)); | 294 | s->client_get, GNUNET_i2s (&s->target)); |
292 | 295 | ||
293 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); | 296 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); |
@@ -362,6 +365,7 @@ client_receive_mst_cb (void *cls, void *client, | |||
362 | return GNUNET_OK; | 365 | return GNUNET_OK; |
363 | } | 366 | } |
364 | 367 | ||
368 | |||
365 | static void | 369 | static void |
366 | client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 370 | client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
367 | { | 371 | { |
@@ -372,29 +376,26 @@ client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
372 | GNUNET_break (0); | 376 | GNUNET_break (0); |
373 | return; | 377 | return; |
374 | } | 378 | } |
375 | |||
376 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | 379 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; |
377 | |||
378 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 380 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
379 | return; | 381 | return; |
380 | |||
381 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | 382 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, |
382 | "Client: %X Waking up receive handle\n", s->client_get); | 383 | "Client: %p Waking up receive handle\n", s->client_get); |
383 | |||
384 | if (s->client_get != NULL) | 384 | if (s->client_get != NULL) |
385 | curl_easy_pause (s->client_get, CURLPAUSE_CONT); | 385 | curl_easy_pause (s->client_get, CURLPAUSE_CONT); |
386 | |||
387 | } | 386 | } |
388 | 387 | ||
388 | |||
389 | /** | 389 | /** |
390 | * Callback method used with libcurl | 390 | * Callback method used with libcurl |
391 | * Method is called when libcurl needs to write data during sending | 391 | * Method is called when libcurl needs to write data during sending |
392 | * @param stream pointer where to write data | 392 | * |
393 | * @param size size of an individual element | 393 | * @param stream pointer where to write data |
394 | * @param nmemb count of elements that can be written to the buffer | 394 | * @param size size of an individual element |
395 | * @param cls destination pointer, passed to the libcurl handle | 395 | * @param nmemb count of elements that can be written to the buffer |
396 | * @return bytes read from stream | 396 | * @param cls destination pointer, passed to the libcurl handle |
397 | */ | 397 | * @return bytes read from stream |
398 | */ | ||
398 | static size_t | 399 | static size_t |
399 | client_receive (void *stream, size_t size, size_t nmemb, void *cls) | 400 | client_receive (void *stream, size_t size, size_t nmemb, void *cls) |
400 | { | 401 | { |
@@ -413,7 +414,7 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) | |||
413 | struct GNUNET_TIME_Relative delta = | 414 | struct GNUNET_TIME_Relative delta = |
414 | GNUNET_TIME_absolute_get_difference (now, s->next_receive); | 415 | GNUNET_TIME_absolute_get_difference (now, s->next_receive); |
415 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 416 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
416 | "Client: %X No inbound bandwidth available! Next read was delayed for %llu ms\n", | 417 | "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n", |
417 | s->client_get, delta.rel_value); | 418 | s->client_get, delta.rel_value); |
418 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | 419 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) |
419 | { | 420 | { |
@@ -424,19 +425,17 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) | |||
424 | GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); | 425 | GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); |
425 | return CURLPAUSE_ALL; | 426 | return CURLPAUSE_ALL; |
426 | } | 427 | } |
427 | 428 | if (NULL == s->msg_tk) | |
428 | |||
429 | if (s->msg_tk == NULL) | ||
430 | s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); | 429 | s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); |
431 | |||
432 | GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO); | 430 | GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO); |
433 | |||
434 | return len; | 431 | return len; |
435 | } | 432 | } |
436 | 433 | ||
434 | |||
437 | /** | 435 | /** |
438 | * Callback method used with libcurl | 436 | * Callback method used with libcurl |
439 | * Method is called when libcurl needs to read data during sending | 437 | * Method is called when libcurl needs to read data during sending |
438 | * | ||
440 | * @param stream pointer where to write data | 439 | * @param stream pointer where to write data |
441 | * @param size size of an individual element | 440 | * @param size size of an individual element |
442 | * @param nmemb count of elements that can be written to the buffer | 441 | * @param nmemb count of elements that can be written to the buffer |
@@ -448,67 +447,46 @@ client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) | |||
448 | { | 447 | { |
449 | struct Session *s = cls; | 448 | struct Session *s = cls; |
450 | struct Plugin *plugin = s->plugin; | 449 | struct Plugin *plugin = s->plugin; |
450 | struct HTTP_Message *msg = s->msg_head; | ||
451 | size_t bytes_sent = 0; | 451 | size_t bytes_sent = 0; |
452 | size_t len; | 452 | size_t len; |
453 | 453 | ||
454 | if (GNUNET_YES != exist_session(plugin, s)) | 454 | if (GNUNET_YES != exist_session(plugin, s)) |
455 | { | 455 | { |
456 | GNUNET_break (0); | 456 | GNUNET_break (0); |
457 | return GNUNET_SYSERR; | 457 | return 0; |
458 | } | 458 | } |
459 | 459 | if (NULL == msg) | |
460 | struct HTTP_Message *msg = s->msg_head; | ||
461 | |||
462 | if (msg == NULL) | ||
463 | { | 460 | { |
464 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 461 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
465 | "Client: %X Nothing to send! Suspending PUT handle!\n", | 462 | "Client: %p Nothing to send! Suspending PUT handle!\n", |
466 | s->client_put); | 463 | s->client_put); |
467 | s->client_put_paused = GNUNET_YES; | 464 | s->client_put_paused = GNUNET_YES; |
468 | return CURL_READFUNC_PAUSE; | 465 | return CURL_READFUNC_PAUSE; |
469 | } | 466 | } |
470 | |||
471 | GNUNET_assert (msg != NULL); | ||
472 | /* data to send */ | 467 | /* data to send */ |
473 | if (msg->pos < msg->size) | 468 | GNUNET_assert (msg->pos < msg->size); |
474 | { | 469 | /* calculate how much fits in buffer */ |
475 | /* data fit in buffer */ | 470 | bytes_sent = GNUNET_MIN (msg->size - msg->pos, |
476 | if ((msg->size - msg->pos) <= (size * nmemb)) | 471 | size * nmemb); |
477 | { | 472 | memcpy (stream, &msg->buf[msg->pos], len); |
478 | len = (msg->size - msg->pos); | 473 | msg->pos += len; |
479 | memcpy (stream, &msg->buf[msg->pos], len); | 474 | bytes_sent = len; |
480 | msg->pos += len; | ||
481 | bytes_sent = len; | ||
482 | } | ||
483 | else | ||
484 | { | ||
485 | len = size * nmemb; | ||
486 | memcpy (stream, &msg->buf[msg->pos], len); | ||
487 | msg->pos += len; | ||
488 | bytes_sent = len; | ||
489 | } | ||
490 | } | ||
491 | /* no data to send */ | ||
492 | else | ||
493 | { | ||
494 | GNUNET_assert (0); | ||
495 | bytes_sent = 0; | ||
496 | } | ||
497 | |||
498 | if (msg->pos == msg->size) | 475 | if (msg->pos == msg->size) |
499 | { | 476 | { |
500 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 477 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
501 | "Client: %X Message with %u bytes sent, removing message from queue\n", | 478 | "Client: %p Message with %u bytes sent, removing message from queue\n", |
502 | s->client_put, msg->size, msg->pos); | 479 | s->client_put, msg->size, msg->pos); |
503 | /* Calling transmit continuation */ | 480 | /* Calling transmit continuation */ |
481 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
504 | if (NULL != msg->transmit_cont) | 482 | if (NULL != msg->transmit_cont) |
505 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); | 483 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); |
506 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
507 | GNUNET_free (msg); | 484 | GNUNET_free (msg); |
508 | } | 485 | } |
509 | return bytes_sent; | 486 | return bytes_sent; |
510 | } | 487 | } |
511 | 488 | ||
489 | |||
512 | int | 490 | int |
513 | client_connect (struct Session *s) | 491 | client_connect (struct Session *s) |
514 | { | 492 | { |
@@ -631,6 +609,7 @@ client_connect (struct Session *s) | |||
631 | return res; | 609 | return res; |
632 | } | 610 | } |
633 | 611 | ||
612 | |||
634 | int | 613 | int |
635 | client_start (struct Plugin *plugin) | 614 | client_start (struct Plugin *plugin) |
636 | { | 615 | { |
@@ -651,6 +630,7 @@ client_start (struct Plugin *plugin) | |||
651 | return res; | 630 | return res; |
652 | } | 631 | } |
653 | 632 | ||
633 | |||
654 | void | 634 | void |
655 | client_stop (struct Plugin *plugin) | 635 | client_stop (struct Plugin *plugin) |
656 | { | 636 | { |