aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r--src/transport/plugin_transport_http_client.c114
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)
73static void 73static void
74client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 74client_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
248int 251int
249client_disconnect (struct Session *s) 252client_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
365static void 369static void
366client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 370client_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 */
398static size_t 399static size_t
399client_receive (void *stream, size_t size, size_t nmemb, void *cls) 400client_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
512int 490int
513client_connect (struct Session *s) 491client_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
634int 613int
635client_start (struct Plugin *plugin) 614client_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
654void 634void
655client_stop (struct Plugin *plugin) 635client_stop (struct Plugin *plugin)
656{ 636{