diff options
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 161 |
1 files changed, 144 insertions, 17 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index eec8939c7..df164aa4b 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -40,6 +40,18 @@ server_log (void *arg, const char *fmt, va_list ap) | |||
40 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: %s\n", text); | 40 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: %s\n", text); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct ServerConnection | ||
44 | { | ||
45 | /* _RECV or _SEND */ | ||
46 | int direction; | ||
47 | |||
48 | /* should this connection get disconnected? GNUNET_YES/NO */ | ||
49 | int disconnect; | ||
50 | |||
51 | struct Session *session; | ||
52 | struct MHD_Connection * mhd_conn; | ||
53 | }; | ||
54 | |||
43 | /** | 55 | /** |
44 | * Check if incoming connection is accepted. | 56 | * Check if incoming connection is accepted. |
45 | * NOTE: Here every connection is accepted | 57 | * NOTE: Here every connection is accepted |
@@ -233,15 +245,16 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
233 | void **httpSessionCache) | 245 | void **httpSessionCache) |
234 | { | 246 | { |
235 | struct Plugin *plugin = cls; | 247 | struct Plugin *plugin = cls; |
236 | struct Session *s = *httpSessionCache; | 248 | struct ServerConnection *sc = *httpSessionCache; |
249 | struct Session *s = NULL; | ||
250 | |||
237 | int res = MHD_YES; | 251 | int res = MHD_YES; |
238 | struct MHD_Response *response; | 252 | struct MHD_Response *response; |
239 | 253 | ||
240 | GNUNET_assert (cls != NULL); | 254 | GNUNET_assert (cls != NULL); |
241 | /* new connection */ | 255 | /* new connection */ |
242 | if (s == NULL) | 256 | if (sc == NULL) |
243 | { | 257 | { |
244 | |||
245 | uint32_t tag; | 258 | uint32_t tag; |
246 | const union MHD_ConnectionInfo *conn_info; | 259 | const union MHD_ConnectionInfo *conn_info; |
247 | size_t addrlen; | 260 | size_t addrlen; |
@@ -319,7 +332,11 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
319 | if (t == NULL) | 332 | if (t == NULL) |
320 | goto create; | 333 | goto create; |
321 | 334 | ||
322 | if ((direction == _SEND) && (t->server_get != NULL)) | 335 | #if VERBOSE_SERVER |
336 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Found existing semi-session for `%s'\n", GNUNET_i2s (&target)); | ||
337 | #endif | ||
338 | |||
339 | if ((direction == _SEND) && (t->server_send != NULL)) | ||
323 | { | 340 | { |
324 | #if VERBOSE_SERVER | 341 | #if VERBOSE_SERVER |
325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate GET session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); | 342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate GET session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); |
@@ -329,7 +346,6 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
329 | else | 346 | else |
330 | { | 347 | { |
331 | s = t; | 348 | s = t; |
332 | s->server_get = s; | ||
333 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); | 349 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); |
334 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); | 350 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); |
335 | #if VERBOSE_SERVER | 351 | #if VERBOSE_SERVER |
@@ -338,7 +354,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
338 | 354 | ||
339 | goto found; | 355 | goto found; |
340 | } | 356 | } |
341 | if ((direction == _RECEIVE) && (t->server_put != NULL)) | 357 | if ((direction == _RECEIVE) && (t->server_recv != NULL)) |
342 | { | 358 | { |
343 | #if VERBOSE_SERVER | 359 | #if VERBOSE_SERVER |
344 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate PUT session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); | 360 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate PUT session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); |
@@ -348,7 +364,6 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
348 | else | 364 | else |
349 | { | 365 | { |
350 | s = t; | 366 | s = t; |
351 | s->server_put = s; | ||
352 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); | 367 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); |
353 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); | 368 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); |
354 | #if VERBOSE_SERVER | 369 | #if VERBOSE_SERVER |
@@ -373,9 +388,9 @@ create: | |||
373 | s->inbound = GNUNET_YES; | 388 | s->inbound = GNUNET_YES; |
374 | s->tag= tag; | 389 | s->tag= tag; |
375 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) | 390 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) |
376 | s->server_put = s; | 391 | s->server_recv = s; |
377 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) | 392 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) |
378 | s->server_get = s; | 393 | s->server_send = s; |
379 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); | 394 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); |
380 | 395 | ||
381 | goto found; | 396 | goto found; |
@@ -388,11 +403,36 @@ error: | |||
388 | 403 | ||
389 | 404 | ||
390 | found: | 405 | found: |
391 | (*httpSessionCache) = s; | ||
392 | return MHD_YES; | ||
393 | 406 | ||
407 | |||
408 | sc = GNUNET_malloc (sizeof (struct ServerConnection)); | ||
409 | sc->mhd_conn = mhd_connection; | ||
410 | sc->direction = direction; | ||
411 | sc->session = s; | ||
412 | if (direction == _SEND) | ||
413 | s->server_send = sc; | ||
414 | if (direction == _RECEIVE) | ||
415 | s->server_recv = sc; | ||
416 | |||
417 | (*httpSessionCache) = sc; | ||
418 | return MHD_YES; | ||
394 | } | 419 | } |
420 | /* existing connection */ | ||
421 | sc = (*httpSessionCache); | ||
422 | s = sc->session; | ||
395 | 423 | ||
424 | /* connection is to be disconnected*/ | ||
425 | if (sc->disconnect == GNUNET_YES) | ||
426 | { | ||
427 | response = MHD_create_response_from_data (strlen ("Thank you!"), "Thank you!", MHD_NO, MHD_NO); | ||
428 | res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); | ||
429 | #if VERBOSE_SERVER | ||
430 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
431 | "Sent HTTP/1.1: 200 OK as PUT Response\n"); | ||
432 | #endif | ||
433 | MHD_destroy_response (response); | ||
434 | return MHD_YES; | ||
435 | } | ||
396 | 436 | ||
397 | return res; | 437 | return res; |
398 | } | 438 | } |
@@ -401,20 +441,95 @@ static void | |||
401 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, | 441 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, |
402 | void **httpSessionCache) | 442 | void **httpSessionCache) |
403 | { | 443 | { |
404 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_disconnect_cb\n"); | 444 | struct ServerConnection *sc = *httpSessionCache; |
405 | /* | 445 | struct ServerConnection *tc = *httpSessionCache; |
406 | struct Session *s = *httpSessionCache; | 446 | struct Session * s = NULL; |
447 | struct Session * t = NULL; | ||
448 | struct Plugin * plugin = NULL; | ||
407 | 449 | ||
408 | if (s != NULL) | 450 | if (sc == NULL) |
451 | return; | ||
452 | |||
453 | s = sc->session; | ||
454 | plugin = s-> plugin; | ||
455 | if (sc->direction == _SEND) | ||
456 | { | ||
457 | #if VERBOSE_SERVER | ||
458 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
459 | "Server: peer `%s' PUT on address `%s' disconnected\n", | ||
460 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); | ||
461 | #endif | ||
462 | s->server_send = NULL; | ||
463 | /* FIXME miminimize timeout here */ | ||
464 | if (s->server_recv != NULL) | ||
465 | { | ||
466 | tc = s->server_recv; | ||
467 | tc->disconnect = GNUNET_YES; | ||
468 | } | ||
469 | } | ||
470 | if (sc->direction == _RECEIVE) | ||
409 | { | 471 | { |
472 | #if VERBOSE_SERVER | ||
473 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
474 | "Server: peer `%s' GET on address `%s' disconnected\n", | ||
475 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); | ||
476 | #endif | ||
477 | s->server_recv = NULL; | ||
478 | //MHD_ | ||
479 | if (s->server_send != NULL) | ||
480 | { | ||
481 | tc = s->server_send; | ||
482 | tc->disconnect = GNUNET_YES; | ||
483 | } | ||
484 | } | ||
485 | GNUNET_free (sc); | ||
486 | |||
487 | t = plugin->server_semi_head; | ||
488 | while (t != NULL) | ||
489 | { | ||
490 | if (t == s) | ||
491 | { | ||
492 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); | ||
493 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); | ||
494 | break; | ||
495 | } | ||
496 | t = t->next; | ||
497 | } | ||
498 | |||
499 | if ((s->server_send == NULL) && (s->server_recv == NULL)) | ||
500 | { | ||
501 | #if VERBOSE_SERVER | ||
502 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
503 | "Server: peer `%s' on address `%s' disconnected\n", | ||
504 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); | ||
505 | #endif | ||
410 | notify_session_end(s->plugin, &s->target, s); | 506 | notify_session_end(s->plugin, &s->target, s); |
411 | } | 507 | } |
412 | */ | ||
413 | } | 508 | } |
414 | 509 | ||
415 | int | 510 | int |
416 | server_disconnect (struct Session *s) | 511 | server_disconnect (struct Session *s) |
417 | { | 512 | { |
513 | struct Plugin *plugin = s->plugin; | ||
514 | struct Session *t = plugin->head; | ||
515 | |||
516 | while (t != NULL) | ||
517 | { | ||
518 | if (t->inbound == GNUNET_YES) | ||
519 | { | ||
520 | if (t->server_send != NULL) | ||
521 | { | ||
522 | ((struct ServerConnection *) t->server_send)->disconnect = GNUNET_YES; | ||
523 | } | ||
524 | if (t->server_send != NULL) | ||
525 | { | ||
526 | ((struct ServerConnection *) t->server_send)->disconnect = GNUNET_YES; | ||
527 | } | ||
528 | } | ||
529 | t = t->next; | ||
530 | } | ||
531 | |||
532 | |||
418 | return GNUNET_OK; | 533 | return GNUNET_OK; |
419 | } | 534 | } |
420 | 535 | ||
@@ -659,6 +774,9 @@ server_start (struct Plugin *plugin) | |||
659 | void | 774 | void |
660 | server_stop (struct Plugin *plugin) | 775 | server_stop (struct Plugin *plugin) |
661 | { | 776 | { |
777 | struct Session *s = NULL; | ||
778 | struct Session *t = NULL; | ||
779 | |||
662 | if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) | 780 | if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) |
663 | { | 781 | { |
664 | GNUNET_SCHEDULER_cancel (plugin->server_v4_task); | 782 | GNUNET_SCHEDULER_cancel (plugin->server_v4_task); |
@@ -682,6 +800,15 @@ server_stop (struct Plugin *plugin) | |||
682 | plugin->server_v6 = NULL; | 800 | plugin->server_v6 = NULL; |
683 | } | 801 | } |
684 | 802 | ||
803 | /* cleaning up semi-sessions never propagated */ | ||
804 | s = plugin->server_semi_head; | ||
805 | while (s != NULL) | ||
806 | { | ||
807 | t = s->next; | ||
808 | delete_session (s); | ||
809 | s = t; | ||
810 | } | ||
811 | |||
685 | #if BUILD_HTTPS | 812 | #if BUILD_HTTPS |
686 | GNUNET_free_non_null (plugin->crypto_init); | 813 | GNUNET_free_non_null (plugin->crypto_init); |
687 | GNUNET_free_non_null (plugin->cert); | 814 | GNUNET_free_non_null (plugin->cert); |