aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r--src/transport/plugin_transport_http_server.c161
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
43struct 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
390found: 405found:
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
401server_disconnect_cb (void *cls, struct MHD_Connection *connection, 441server_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
415int 510int
416server_disconnect (struct Session *s) 511server_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)
659void 774void
660server_stop (struct Plugin *plugin) 775server_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);