diff options
Diffstat (limited to 'src/transport/plugin_transport_http_client_old.c')
-rw-r--r-- | src/transport/plugin_transport_http_client_old.c | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/src/transport/plugin_transport_http_client_old.c b/src/transport/plugin_transport_http_client_old.c new file mode 100644 index 000000000..ff23da974 --- /dev/null +++ b/src/transport/plugin_transport_http_client_old.c | |||
@@ -0,0 +1,645 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2002--2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file transport/plugin_transport_http_client.c | ||
23 | * @brief http transport service plugin | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | |||
27 | #include "plugin_transport_http.h" | ||
28 | |||
29 | static struct Plugin * p; | ||
30 | |||
31 | #if VERBOSE_CURL | ||
32 | /** | ||
33 | * Function to log curl debug messages with GNUNET_log | ||
34 | * @param curl handle | ||
35 | * @param type curl_infotype | ||
36 | * @param data data | ||
37 | * @param size size | ||
38 | * @param cls closure | ||
39 | * @return 0 | ||
40 | */ | ||
41 | static int | ||
42 | client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) | ||
43 | { | ||
44 | if (type == CURLINFO_TEXT) | ||
45 | { | ||
46 | char text[size + 2]; | ||
47 | |||
48 | memcpy (text, data, size); | ||
49 | if (text[size - 1] == '\n') | ||
50 | text[size] = '\0'; | ||
51 | else | ||
52 | { | ||
53 | text[size] = '\n'; | ||
54 | text[size + 1] = '\0'; | ||
55 | } | ||
56 | #if BUILD_HTTPS | ||
57 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https", | ||
58 | "Client: %p - %s", cls, text); | ||
59 | #else | ||
60 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http", | ||
61 | "Client: %p - %s", cls, text); | ||
62 | #endif | ||
63 | } | ||
64 | return 0; | ||
65 | } | ||
66 | #endif | ||
67 | |||
68 | /** | ||
69 | * Task performing curl operations | ||
70 | * @param cls plugin as closure | ||
71 | * @param tc gnunet scheduler task context | ||
72 | */ | ||
73 | static void | ||
74 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Function setting up file descriptors and scheduling task to run | ||
79 | * | ||
80 | * @param plugin plugin as closure | ||
81 | * @param now schedule task in 1ms, regardless of what curl may say | ||
82 | * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok | ||
83 | */ | ||
84 | static int | ||
85 | client_schedule (struct Plugin *plugin, int now) | ||
86 | { | ||
87 | fd_set rs; | ||
88 | fd_set ws; | ||
89 | fd_set es; | ||
90 | int max; | ||
91 | struct GNUNET_NETWORK_FDSet *grs; | ||
92 | struct GNUNET_NETWORK_FDSet *gws; | ||
93 | long to; | ||
94 | CURLMcode mret; | ||
95 | struct GNUNET_TIME_Relative timeout; | ||
96 | |||
97 | /* Cancel previous scheduled task */ | ||
98 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
99 | { | ||
100 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
101 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
102 | } | ||
103 | max = -1; | ||
104 | FD_ZERO (&rs); | ||
105 | FD_ZERO (&ws); | ||
106 | FD_ZERO (&es); | ||
107 | mret = curl_multi_fdset (plugin->client_mh, &rs, &ws, &es, &max); | ||
108 | if (mret != CURLM_OK) | ||
109 | { | ||
110 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
111 | "curl_multi_fdset", __FILE__, __LINE__, | ||
112 | curl_multi_strerror (mret)); | ||
113 | return GNUNET_SYSERR; | ||
114 | } | ||
115 | mret = curl_multi_timeout (plugin->client_mh, &to); | ||
116 | if (to == -1) | ||
117 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); | ||
118 | else | ||
119 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); | ||
120 | if (now == GNUNET_YES) | ||
121 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; | ||
122 | |||
123 | if (mret != CURLM_OK) | ||
124 | { | ||
125 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
126 | "curl_multi_timeout", __FILE__, __LINE__, | ||
127 | curl_multi_strerror (mret)); | ||
128 | return GNUNET_SYSERR; | ||
129 | } | ||
130 | |||
131 | grs = GNUNET_NETWORK_fdset_create (); | ||
132 | gws = GNUNET_NETWORK_fdset_create (); | ||
133 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | ||
134 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | ||
135 | |||
136 | plugin->client_perform_task = | ||
137 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
138 | timeout, grs, gws, | ||
139 | &client_run, plugin); | ||
140 | GNUNET_NETWORK_fdset_destroy (gws); | ||
141 | GNUNET_NETWORK_fdset_destroy (grs); | ||
142 | return GNUNET_OK; | ||
143 | } | ||
144 | |||
145 | |||
146 | int | ||
147 | client_send (struct Session *s, struct HTTP_Message *msg) | ||
148 | { | ||
149 | GNUNET_assert (s != NULL); | ||
150 | GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); | ||
151 | |||
152 | if (GNUNET_YES != exist_session(p, s)) | ||
153 | { | ||
154 | GNUNET_break (0); | ||
155 | return GNUNET_SYSERR; | ||
156 | } | ||
157 | if (s->client_put_paused == GNUNET_YES) | ||
158 | { | ||
159 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | ||
160 | "Client: %p was suspended, unpausing\n", s->client_put); | ||
161 | s->client_put_paused = GNUNET_NO; | ||
162 | curl_easy_pause (s->client_put, CURLPAUSE_CONT); | ||
163 | } | ||
164 | client_schedule (s->plugin, GNUNET_YES); | ||
165 | |||
166 | return GNUNET_OK; | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Task performing curl operations | ||
172 | * | ||
173 | * @param cls plugin as closure | ||
174 | * @param tc gnunet scheduler task context | ||
175 | */ | ||
176 | static void | ||
177 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
178 | { | ||
179 | struct Plugin *plugin = cls; | ||
180 | int running; | ||
181 | CURLMcode mret; | ||
182 | |||
183 | GNUNET_assert (cls != NULL); | ||
184 | |||
185 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
186 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
187 | return; | ||
188 | |||
189 | do | ||
190 | { | ||
191 | running = 0; | ||
192 | mret = curl_multi_perform (plugin->client_mh, &running); | ||
193 | |||
194 | CURLMsg *msg; | ||
195 | int msgs_left; | ||
196 | |||
197 | while ((msg = curl_multi_info_read (plugin->client_mh, &msgs_left))) | ||
198 | { | ||
199 | CURL *easy_h = msg->easy_handle; | ||
200 | struct Session *s = NULL; | ||
201 | char *d = (char *) s; | ||
202 | |||
203 | if (easy_h == NULL) | ||
204 | { | ||
205 | GNUNET_break (0); | ||
206 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
207 | "Client: connection to ended with reason %i: `%s', %i handles running\n", | ||
208 | msg->data.result, | ||
209 | curl_easy_strerror (msg->data.result), running); | ||
210 | continue; | ||
211 | } | ||
212 | |||
213 | GNUNET_assert (CURLE_OK == | ||
214 | curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); | ||
215 | s = (struct Session *) d; | ||
216 | |||
217 | if (GNUNET_YES != exist_session(plugin, s)) | ||
218 | { | ||
219 | GNUNET_break (0); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | GNUNET_assert (s != NULL); | ||
224 | if (msg->msg == CURLMSG_DONE) | ||
225 | { | ||
226 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
227 | "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", | ||
228 | msg->easy_handle, GNUNET_i2s (&s->target), | ||
229 | http_plugin_address_to_string (NULL, s->addr, | ||
230 | s->addrlen), | ||
231 | msg->data.result, | ||
232 | curl_easy_strerror (msg->data.result)); | ||
233 | |||
234 | /* Disconnect other transmission direction and tell transport */ | ||
235 | client_disconnect (s); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | while (mret == CURLM_CALL_MULTI_PERFORM); | ||
240 | client_schedule (plugin, GNUNET_NO); | ||
241 | } | ||
242 | |||
243 | |||
244 | int | ||
245 | client_disconnect (struct Session *s) | ||
246 | { | ||
247 | int res = GNUNET_OK; | ||
248 | CURLMcode mret; | ||
249 | struct Plugin *plugin = s->plugin; | ||
250 | struct HTTP_Message *msg; | ||
251 | struct HTTP_Message *t; | ||
252 | |||
253 | if (GNUNET_YES != exist_session(plugin, s)) | ||
254 | { | ||
255 | GNUNET_break (0); | ||
256 | return GNUNET_SYSERR; | ||
257 | } | ||
258 | |||
259 | if (s->client_put != NULL) | ||
260 | { | ||
261 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
262 | "Client: %p / %p Deleting outbound PUT session to peer `%s'\n", | ||
263 | s, s->client_put, GNUNET_i2s (&s->target)); | ||
264 | |||
265 | /* remove curl handle from multi handle */ | ||
266 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); | ||
267 | if (mret != CURLM_OK) | ||
268 | { | ||
269 | /* clean up easy handle, handle is now invalid and free'd */ | ||
270 | res = GNUNET_SYSERR; | ||
271 | GNUNET_break (0); | ||
272 | } | ||
273 | curl_easy_cleanup (s->client_put); | ||
274 | s->client_put = NULL; | ||
275 | } | ||
276 | |||
277 | |||
278 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
279 | { | ||
280 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
281 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
282 | } | ||
283 | |||
284 | if (s->client_get != NULL) | ||
285 | { | ||
286 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
287 | "Client: %p / %p Deleting outbound GET session to peer `%s'\n", | ||
288 | s, | ||
289 | s->client_get, GNUNET_i2s (&s->target)); | ||
290 | |||
291 | /* remove curl handle from multi handle */ | ||
292 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); | ||
293 | if (mret != CURLM_OK) | ||
294 | { | ||
295 | /* clean up easy handle, handle is now invalid and free'd */ | ||
296 | res = GNUNET_SYSERR; | ||
297 | GNUNET_break (0); | ||
298 | } | ||
299 | curl_easy_cleanup (s->client_get); | ||
300 | s->client_get = NULL; | ||
301 | } | ||
302 | |||
303 | msg = s->msg_head; | ||
304 | while (msg != NULL) | ||
305 | { | ||
306 | t = msg->next; | ||
307 | if (NULL != msg->transmit_cont) | ||
308 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
309 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
310 | GNUNET_free (msg); | ||
311 | msg = t; | ||
312 | } | ||
313 | |||
314 | plugin->cur_connections -= 2; | ||
315 | |||
316 | notify_session_end (plugin, &s->target, s); | ||
317 | |||
318 | GNUNET_assert (plugin->outbound_sessions > 0); | ||
319 | plugin->outbound_sessions --; | ||
320 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
321 | "# HTTP outbound sessions", | ||
322 | plugin->outbound_sessions, | ||
323 | GNUNET_NO); | ||
324 | |||
325 | /* Re-schedule since handles have changed */ | ||
326 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
327 | { | ||
328 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
329 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
330 | } | ||
331 | client_schedule (plugin, GNUNET_YES); | ||
332 | |||
333 | return res; | ||
334 | } | ||
335 | |||
336 | static int | ||
337 | client_receive_mst_cb (void *cls, void *client, | ||
338 | const struct GNUNET_MessageHeader *message) | ||
339 | { | ||
340 | struct Session *s = cls; | ||
341 | struct GNUNET_TIME_Relative delay; | ||
342 | |||
343 | if (GNUNET_YES != exist_session(p, s)) | ||
344 | { | ||
345 | GNUNET_break (0); | ||
346 | return GNUNET_OK; | ||
347 | } | ||
348 | |||
349 | delay = http_plugin_receive (s, &s->target, message, s, s->addr, s->addrlen); | ||
350 | s->next_receive = | ||
351 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); | ||
352 | |||
353 | if (GNUNET_TIME_absolute_get ().abs_value < s->next_receive.abs_value) | ||
354 | { | ||
355 | struct Plugin *plugin = s->plugin; | ||
356 | |||
357 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
358 | "Client: peer `%s' address `%s' next read delayed for %llu ms\n", | ||
359 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen), | ||
360 | delay); | ||
361 | } | ||
362 | return GNUNET_OK; | ||
363 | } | ||
364 | |||
365 | |||
366 | static void | ||
367 | client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
368 | { | ||
369 | struct Session *s = cls; | ||
370 | |||
371 | if (GNUNET_YES != exist_session(p, s)) | ||
372 | { | ||
373 | GNUNET_break (0); | ||
374 | return; | ||
375 | } | ||
376 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
377 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
378 | return; | ||
379 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | ||
380 | "Client: %p Waking up receive handle\n", s->client_get); | ||
381 | if (s->client_get != NULL) | ||
382 | curl_easy_pause (s->client_get, CURLPAUSE_CONT); | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Callback method used with libcurl | ||
388 | * Method is called when libcurl needs to write data during sending | ||
389 | * | ||
390 | * @param stream pointer where to write data | ||
391 | * @param size size of an individual element | ||
392 | * @param nmemb count of elements that can be written to the buffer | ||
393 | * @param cls destination pointer, passed to the libcurl handle | ||
394 | * @return bytes read from stream | ||
395 | */ | ||
396 | static size_t | ||
397 | client_receive (void *stream, size_t size, size_t nmemb, void *cls) | ||
398 | { | ||
399 | struct Session *s = cls; | ||
400 | struct GNUNET_TIME_Absolute now; | ||
401 | size_t len = size * nmemb; | ||
402 | struct Plugin *plugin = s->plugin; | ||
403 | |||
404 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
405 | "Client: Received %u bytes from peer `%s'\n", len, | ||
406 | GNUNET_i2s (&s->target)); | ||
407 | now = GNUNET_TIME_absolute_get (); | ||
408 | if (now.abs_value < s->next_receive.abs_value) | ||
409 | { | ||
410 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
411 | struct GNUNET_TIME_Relative delta = | ||
412 | GNUNET_TIME_absolute_get_difference (now, s->next_receive); | ||
413 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
414 | "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n", | ||
415 | s->client_get, delta.rel_value); | ||
416 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
417 | { | ||
418 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
419 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
420 | } | ||
421 | s->recv_wakeup_task = | ||
422 | GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); | ||
423 | return CURLPAUSE_ALL; | ||
424 | } | ||
425 | if (NULL == s->msg_tk) | ||
426 | s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); | ||
427 | GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO); | ||
428 | return len; | ||
429 | } | ||
430 | |||
431 | |||
432 | /** | ||
433 | * Callback method used with libcurl | ||
434 | * Method is called when libcurl needs to read data during sending | ||
435 | * | ||
436 | * @param stream pointer where to write data | ||
437 | * @param size size of an individual element | ||
438 | * @param nmemb count of elements that can be written to the buffer | ||
439 | * @param cls source pointer, passed to the libcurl handle | ||
440 | * @return bytes written to stream, returning 0 will terminate connection! | ||
441 | */ | ||
442 | static size_t | ||
443 | client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) | ||
444 | { | ||
445 | struct Session *s = cls; | ||
446 | struct Plugin *plugin = s->plugin; | ||
447 | struct HTTP_Message *msg = s->msg_head; | ||
448 | size_t len; | ||
449 | |||
450 | if (GNUNET_YES != exist_session(plugin, s)) | ||
451 | { | ||
452 | GNUNET_break (0); | ||
453 | return 0; | ||
454 | } | ||
455 | if (NULL == msg) | ||
456 | { | ||
457 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
458 | "Client: %p Nothing to send! Suspending PUT handle!\n", | ||
459 | s->client_put); | ||
460 | s->client_put_paused = GNUNET_YES; | ||
461 | return CURL_READFUNC_PAUSE; | ||
462 | } | ||
463 | /* data to send */ | ||
464 | GNUNET_assert (msg->pos < msg->size); | ||
465 | /* calculate how much fits in buffer */ | ||
466 | len = GNUNET_MIN (msg->size - msg->pos, | ||
467 | size * nmemb); | ||
468 | memcpy (stream, &msg->buf[msg->pos], len); | ||
469 | msg->pos += len; | ||
470 | if (msg->pos == msg->size) | ||
471 | { | ||
472 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
473 | "Client: %p Message with %u bytes sent, removing message from queue\n", | ||
474 | s->client_put, msg->size, msg->pos); | ||
475 | /* Calling transmit continuation */ | ||
476 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
477 | if (NULL != msg->transmit_cont) | ||
478 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); | ||
479 | GNUNET_free (msg); | ||
480 | } | ||
481 | return len; | ||
482 | } | ||
483 | |||
484 | |||
485 | int | ||
486 | client_connect (struct Session *s) | ||
487 | { | ||
488 | struct Plugin *plugin = s->plugin; | ||
489 | int res = GNUNET_OK; | ||
490 | char *url; | ||
491 | CURLMcode mret; | ||
492 | |||
493 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
494 | "Initiating outbound session peer `%s'\n", | ||
495 | GNUNET_i2s (&s->target)); | ||
496 | s->inbound = GNUNET_NO; | ||
497 | plugin->last_tag++; | ||
498 | /* create url */ | ||
499 | GNUNET_asprintf (&url, "%s%s;%u", | ||
500 | http_plugin_address_to_string (plugin, s->addr, s->addrlen), | ||
501 | GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey), | ||
502 | plugin->last_tag); | ||
503 | #if 0 | ||
504 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "URL `%s'\n", url); | ||
505 | #endif | ||
506 | /* create get connection */ | ||
507 | s->client_get = curl_easy_init (); | ||
508 | #if VERBOSE_CURL | ||
509 | curl_easy_setopt (s->client_get, CURLOPT_VERBOSE, 1L); | ||
510 | curl_easy_setopt (s->client_get, CURLOPT_DEBUGFUNCTION, &client_log); | ||
511 | curl_easy_setopt (s->client_get, CURLOPT_DEBUGDATA, s->client_get); | ||
512 | #endif | ||
513 | #if BUILD_HTTPS | ||
514 | curl_easy_setopt (s->client_get, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); | ||
515 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYPEER, 0); | ||
516 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYHOST, 0); | ||
517 | #endif | ||
518 | curl_easy_setopt (s->client_get, CURLOPT_URL, url); | ||
519 | //curl_easy_setopt (s->client_get, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); | ||
520 | //curl_easy_setopt (s->client_get, CURLOPT_WRITEHEADER, ps); | ||
521 | curl_easy_setopt (s->client_get, CURLOPT_READFUNCTION, client_send_cb); | ||
522 | curl_easy_setopt (s->client_get, CURLOPT_READDATA, s); | ||
523 | curl_easy_setopt (s->client_get, CURLOPT_WRITEFUNCTION, client_receive); | ||
524 | curl_easy_setopt (s->client_get, CURLOPT_WRITEDATA, s); | ||
525 | curl_easy_setopt (s->client_get, CURLOPT_TIMEOUT_MS, | ||
526 | (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
527 | curl_easy_setopt (s->client_get, CURLOPT_PRIVATE, s); | ||
528 | curl_easy_setopt (s->client_get, CURLOPT_CONNECTTIMEOUT_MS, | ||
529 | (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); | ||
530 | curl_easy_setopt (s->client_get, CURLOPT_BUFFERSIZE, | ||
531 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
532 | #if CURL_TCP_NODELAY | ||
533 | curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); | ||
534 | #endif | ||
535 | |||
536 | /* create put connection */ | ||
537 | s->client_put = curl_easy_init (); | ||
538 | #if VERBOSE_CURL | ||
539 | curl_easy_setopt (s->client_put, CURLOPT_VERBOSE, 1L); | ||
540 | curl_easy_setopt (s->client_put, CURLOPT_DEBUGFUNCTION, &client_log); | ||
541 | curl_easy_setopt (s->client_put, CURLOPT_DEBUGDATA, s->client_put); | ||
542 | #endif | ||
543 | #if BUILD_HTTPS | ||
544 | curl_easy_setopt (s->client_put, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); | ||
545 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYPEER, 0); | ||
546 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYHOST, 0); | ||
547 | #endif | ||
548 | curl_easy_setopt (s->client_put, CURLOPT_URL, url); | ||
549 | curl_easy_setopt (s->client_put, CURLOPT_PUT, 1L); | ||
550 | //curl_easy_setopt (s->client_put, CURLOPT_HEADERFUNCTION, &curl_put_header_cb); | ||
551 | //curl_easy_setopt (s->client_put, CURLOPT_WRITEHEADER, ps); | ||
552 | curl_easy_setopt (s->client_put, CURLOPT_READFUNCTION, client_send_cb); | ||
553 | curl_easy_setopt (s->client_put, CURLOPT_READDATA, s); | ||
554 | curl_easy_setopt (s->client_put, CURLOPT_WRITEFUNCTION, client_receive); | ||
555 | curl_easy_setopt (s->client_put, CURLOPT_WRITEDATA, s); | ||
556 | curl_easy_setopt (s->client_put, CURLOPT_TIMEOUT_MS, | ||
557 | (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
558 | curl_easy_setopt (s->client_put, CURLOPT_PRIVATE, s); | ||
559 | curl_easy_setopt (s->client_put, CURLOPT_CONNECTTIMEOUT_MS, | ||
560 | (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); | ||
561 | curl_easy_setopt (s->client_put, CURLOPT_BUFFERSIZE, | ||
562 | 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
563 | #if CURL_TCP_NODELAY | ||
564 | curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); | ||
565 | #endif | ||
566 | |||
567 | GNUNET_free (url); | ||
568 | |||
569 | mret = curl_multi_add_handle (plugin->client_mh, s->client_get); | ||
570 | if (mret != CURLM_OK) | ||
571 | { | ||
572 | curl_easy_cleanup (s->client_get); | ||
573 | res = GNUNET_SYSERR; | ||
574 | GNUNET_break (0); | ||
575 | } | ||
576 | |||
577 | mret = curl_multi_add_handle (plugin->client_mh, s->client_put); | ||
578 | if (mret != CURLM_OK) | ||
579 | { | ||
580 | curl_multi_remove_handle (plugin->client_mh, s->client_get); | ||
581 | curl_easy_cleanup (s->client_get); | ||
582 | curl_easy_cleanup (s->client_put); | ||
583 | res = GNUNET_SYSERR; | ||
584 | GNUNET_break (0); | ||
585 | } | ||
586 | |||
587 | /* Perform connect */ | ||
588 | plugin->cur_connections += 2; | ||
589 | |||
590 | plugin->outbound_sessions ++; | ||
591 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
592 | "# HTTP outbound sessions", | ||
593 | plugin->outbound_sessions, | ||
594 | GNUNET_NO); | ||
595 | |||
596 | /* Re-schedule since handles have changed */ | ||
597 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
598 | { | ||
599 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
600 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
601 | } | ||
602 | plugin->client_perform_task = GNUNET_SCHEDULER_add_now (client_run, plugin); | ||
603 | |||
604 | return res; | ||
605 | } | ||
606 | |||
607 | |||
608 | int | ||
609 | client_start (struct Plugin *plugin) | ||
610 | { | ||
611 | int res = GNUNET_OK; | ||
612 | p = plugin; | ||
613 | |||
614 | curl_global_init (CURL_GLOBAL_ALL); | ||
615 | plugin->client_mh = curl_multi_init (); | ||
616 | |||
617 | if (NULL == plugin->client_mh) | ||
618 | { | ||
619 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
620 | _ | ||
621 | ("Could not initialize curl multi handle, failed to start %s plugin!\n"), | ||
622 | plugin->name); | ||
623 | res = GNUNET_SYSERR; | ||
624 | } | ||
625 | return res; | ||
626 | } | ||
627 | |||
628 | |||
629 | void | ||
630 | client_stop (struct Plugin *plugin) | ||
631 | { | ||
632 | p = NULL; | ||
633 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
634 | { | ||
635 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
636 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
637 | } | ||
638 | |||
639 | curl_multi_cleanup (plugin->client_mh); | ||
640 | curl_global_cleanup (); | ||
641 | } | ||
642 | |||
643 | |||
644 | |||
645 | /* end of plugin_transport_http_client.c */ | ||