aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-27 18:08:00 +0000
committerChristian Grothoff <christian@grothoff.org>2016-08-27 18:08:00 +0000
commite0a43cb194fd22ceaed6905d964f2fcd829b933d (patch)
treee4ec639adcbc441535cdd6e92a5ac3e5ea0be5b9
parent63eb4c75a31654c0b74e2985a0b7861ddaa8d5b3 (diff)
downloadlibmicrohttpd-e0a43cb194fd22ceaed6905d964f2fcd829b933d.tar.gz
libmicrohttpd-e0a43cb194fd22ceaed6905d964f2fcd829b933d.zip
sketching support for upgrade handling
-rw-r--r--ChangeLog4
-rw-r--r--src/include/microhttpd.h7
-rw-r--r--src/microhttpd/connection.c33
-rw-r--r--src/microhttpd/internal.h10
-rw-r--r--src/microhttpd/response.c31
-rw-r--r--src/microhttpd/response.h18
6 files changed, 75 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d61213c..2033ed4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Sat Aug 27 20:07:53 CEST 2016
2 Adding completely *untested* logic for HTTP "Upgrade"
3 handling. -CG
4
1Sat Aug 27 18:20:38 CEST 2016 5Sat Aug 27 18:20:38 CEST 2016
2 Releasing libmicrohttpd 0.9.51. -CG 6 Releasing libmicrohttpd 0.9.51. -CG
3 7
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index ff292280..0a7e4711 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -126,7 +126,7 @@ typedef intptr_t ssize_t;
126 * Current version of the library. 126 * Current version of the library.
127 * 0x01093001 = 1.9.30-1. 127 * 0x01093001 = 1.9.30-1.
128 */ 128 */
129#define MHD_VERSION 0x00095100 129#define MHD_VERSION 0x00095101
130 130
131/** 131/**
132 * MHD-internal return code for "YES". 132 * MHD-internal return code for "YES".
@@ -2221,7 +2221,6 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
2221 uint64_t offset); 2221 uint64_t offset);
2222 2222
2223 2223
2224#if 0
2225/** 2224/**
2226 * Enumeration for actions MHD should perform on the underlying socket 2225 * Enumeration for actions MHD should perform on the underlying socket
2227 * of the upgrade. This API is not finalized, and in particular 2226 * of the upgrade. This API is not finalized, and in particular
@@ -2334,7 +2333,7 @@ typedef void
2334 struct MHD_Connection *connection, 2333 struct MHD_Connection *connection,
2335 const char *extra_in, 2334 const char *extra_in,
2336 size_t extra_in_size, 2335 size_t extra_in_size,
2337 MHD_SOCKET sock, 2336 MHD_socket sock,
2338 struct MHD_UpgradeResponseHandle *urh); 2337 struct MHD_UpgradeResponseHandle *urh);
2339 2338
2340 2339
@@ -2370,7 +2369,7 @@ typedef void
2370_MHD_EXTERN struct MHD_Response * 2369_MHD_EXTERN struct MHD_Response *
2371MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, 2370MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
2372 void *upgrade_handler_cls); 2371 void *upgrade_handler_cls);
2373#endif 2372
2374 2373
2375/** 2374/**
2376 * Destroy a response object and associated resources. Note that 2375 * Destroy a response object and associated resources. Note that
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index ff7f663f..b1b34cef 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -736,7 +736,8 @@ keepalive_possible (struct MHD_Connection *connection)
736 if (NULL == end) 736 if (NULL == end)
737 return MHD_YES; 737 return MHD_YES;
738 if ( (MHD_str_equal_caseless_ (end, "close")) || 738 if ( (MHD_str_equal_caseless_ (end, "close")) ||
739 (MHD_str_equal_caseless_ (end, "upgrade")) ) 739 ( (MHD_str_equal_caseless_ (end, "upgrade")) &&
740 (NULL == connection->response->upgrade_handler) ) )
740 return MHD_NO; 741 return MHD_NO;
741 return MHD_YES; 742 return MHD_YES;
742 } 743 }
@@ -2222,6 +2223,9 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
2222 break; 2223 break;
2223 case MHD_CONNECTION_CLOSED: 2224 case MHD_CONNECTION_CLOSED:
2224 return MHD_YES; 2225 return MHD_YES;
2226 case MHD_CONNECTION_UPGRADE:
2227 EXTRA_CHECK (0);
2228 break;
2225 default: 2229 default:
2226 /* shrink read buffer to how much is actually used */ 2230 /* shrink read buffer to how much is actually used */
2227 MHD_pool_reallocate (connection->pool, 2231 MHD_pool_reallocate (connection->pool,
@@ -2305,7 +2309,8 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2305 do_write (connection); 2309 do_write (connection);
2306 if (connection->state != MHD_CONNECTION_HEADERS_SENDING) 2310 if (connection->state != MHD_CONNECTION_HEADERS_SENDING)
2307 break; 2311 break;
2308 check_write_done (connection, MHD_CONNECTION_HEADERS_SENT); 2312 check_write_done (connection,
2313 MHD_CONNECTION_HEADERS_SENT);
2309 break; 2314 break;
2310 case MHD_CONNECTION_HEADERS_SENT: 2315 case MHD_CONNECTION_HEADERS_SENT:
2311 EXTRA_CHECK (0); 2316 EXTRA_CHECK (0);
@@ -2395,6 +2400,9 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2395 case MHD_TLS_CONNECTION_INIT: 2400 case MHD_TLS_CONNECTION_INIT:
2396 EXTRA_CHECK (0); 2401 EXTRA_CHECK (0);
2397 break; 2402 break;
2403 case MHD_CONNECTION_UPGRADE:
2404 EXTRA_CHECK (0);
2405 break;
2398 default: 2406 default:
2399 EXTRA_CHECK (0); 2407 EXTRA_CHECK (0);
2400 CONNECTION_CLOSE_ERROR (connection, 2408 CONNECTION_CLOSE_ERROR (connection,
@@ -2586,9 +2594,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2586 } 2594 }
2587 if ( (NULL != connection->response) && 2595 if ( (NULL != connection->response) &&
2588 ( (MHD_str_equal_caseless_ (connection->method, 2596 ( (MHD_str_equal_caseless_ (connection->method,
2589 MHD_HTTP_METHOD_POST)) || 2597 MHD_HTTP_METHOD_POST)) ||
2590 (MHD_str_equal_caseless_ (connection->method, 2598 (MHD_str_equal_caseless_ (connection->method,
2591 MHD_HTTP_METHOD_PUT))) ) 2599 MHD_HTTP_METHOD_PUT))) )
2592 { 2600 {
2593 /* we refused (no upload allowed!) */ 2601 /* we refused (no upload allowed!) */
2594 connection->remaining_upload_size = 0; 2602 connection->remaining_upload_size = 0;
@@ -2722,6 +2730,21 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2722 } 2730 }
2723 else 2731 else
2724 socket_start_normal_buffering (connection); 2732 socket_start_normal_buffering (connection);
2733 if (NULL != connection->response->upgrade_handler)
2734 {
2735 /* This connection is "upgraded". Pass socket to application. */
2736 if (MHD_YES !=
2737 MHD_response_execute_upgrade_ (connection->response,
2738 connection))
2739 {
2740 /* upgrade failed, fail hard */
2741 CONNECTION_CLOSE_ERROR (connection,
2742 NULL);
2743 continue;
2744 }
2745 connection->state = MHD_CONNECTION_UPGRADE;
2746 continue;
2747 }
2725 2748
2726 if (connection->have_chunked_upload) 2749 if (connection->have_chunked_upload)
2727 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY; 2750 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
@@ -2882,6 +2905,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2882 case MHD_CONNECTION_CLOSED: 2905 case MHD_CONNECTION_CLOSED:
2883 cleanup_connection (connection); 2906 cleanup_connection (connection);
2884 return MHD_NO; 2907 return MHD_NO;
2908 case MHD_CONNECTION_UPGRADE:
2909 return MHD_YES; /* keep open */
2885 default: 2910 default:
2886 EXTRA_CHECK (0); 2911 EXTRA_CHECK (0);
2887 break; 2912 break;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index d6f1177c..a810d319 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -274,7 +274,6 @@ struct MHD_Response
274 */ 274 */
275 MHD_ContentReaderFreeCallback crfc; 275 MHD_ContentReaderFreeCallback crfc;
276 276
277#if 0
278 /** 277 /**
279 * Application function to call once we are done sending the headers 278 * Application function to call once we are done sending the headers
280 * of the response; NULL unless this is a response created with 279 * of the response; NULL unless this is a response created with
@@ -286,7 +285,6 @@ struct MHD_Response
286 * Closure for @e uh. 285 * Closure for @e uh.
287 */ 286 */
288 void *upgrade_handler_cls; 287 void *upgrade_handler_cls;
289#endif
290 288
291 /** 289 /**
292 * Mutex to synchronize access to @e data, @e size and 290 * Mutex to synchronize access to @e data, @e size and
@@ -476,7 +474,13 @@ enum MHD_CONNECTION_STATE
476 * Handshake messages will be processed in this state & while 474 * Handshake messages will be processed in this state & while
477 * in the #MHD_TLS_HELLO_REQUEST state 475 * in the #MHD_TLS_HELLO_REQUEST state
478 */ 476 */
479 MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1 477 MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1,
478
479 /**
480 * Connection was "upgraded" and socket is now under the
481 * control of the application.
482 */
483 MHD_CONNECTION_UPGRADE = MHD_TLS_CONNECTION_INIT + 1
480 484
481}; 485};
482 486
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index f0ebf5c6..66a1650d 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff 3 Copyright (C) 2007, 2009, 2010, 2016 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,9 @@
29#include "internal.h" 29#include "internal.h"
30#include "response.h" 30#include "response.h"
31#include "mhd_limits.h" 31#include "mhd_limits.h"
32#include "mhd_sockets.h"
33#include "mhd_itc.h"
34#include "connection.h"
32 35
33#if defined(_WIN32) && defined(MHD_W32_MUTEX_) 36#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
34#ifndef WIN32_LEAN_AND_MEAN 37#ifndef WIN32_LEAN_AND_MEAN
@@ -577,7 +580,6 @@ MHD_create_response_from_buffer (size_t size,
577} 580}
578 581
579 582
580#if 0
581/** 583/**
582 * Handle given to the application to manage special 584 * Handle given to the application to manage special
583 * actions relating to MHD responses that "upgrade" 585 * actions relating to MHD responses that "upgrade"
@@ -596,13 +598,13 @@ struct MHD_UpgradeResponseHandle
596 /** 598 /**
597 * The socket we gave to the application (r/w). 599 * The socket we gave to the application (r/w).
598 */ 600 */
599 MHD_SOCKET app_sock; 601 MHD_socket app_socket;
600 602
601 /** 603 /**
602 * If @a app_sock was a socketpair, our end of it, otherwise 604 * If @a app_sock was a socketpair, our end of it, otherwise
603 * #MHD_INVALID_SOCKET; (r/w). 605 * #MHD_INVALID_SOCKET; (r/w).
604 */ 606 */
605 MHD_SOCKET mhd_sock; 607 MHD_socket mhd_socket;
606 608
607}; 609};
608 610
@@ -629,12 +631,12 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
629 case MHD_UPGRADE_ACTION_CLOSE: 631 case MHD_UPGRADE_ACTION_CLOSE:
630 /* Application is done with this connection, tear it down! */ 632 /* Application is done with this connection, tear it down! */
631 if ( (MHD_INVALID_SOCKET != urh->app_socket) && 633 if ( (MHD_INVALID_SOCKET != urh->app_socket) &&
632 (0 != MHD_socket_close (urh->app_socket)) ) 634 (0 != MHD_socket_close_ (urh->app_socket)) )
633 MHD_PANIC ("close failed\n"); 635 MHD_PANIC ("close failed\n");
634 if ( (MHD_INVALID_SOCKET != urh->mhd_socket) && 636 if ( (MHD_INVALID_SOCKET != urh->mhd_socket) &&
635 (0 != MHD_socket_close (urh->mhd_socket)) ) 637 (0 != MHD_socket_close_ (urh->mhd_socket)) )
636 MHD_PANIC ("close failed\n"); 638 MHD_PANIC ("close failed\n");
637 MHD_connection_resume (urh->connection); 639 MHD_resume_connection (urh->connection);
638 MHD_connection_close_ (urh->connection, 640 MHD_connection_close_ (urh->connection,
639 MHD_REQUEST_TERMINATED_COMPLETED_OK); 641 MHD_REQUEST_TERMINATED_COMPLETED_OK);
640 free (urh); 642 free (urh);
@@ -659,9 +661,6 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
659 * @return #MHD_YES on success, #MHD_NO on failure (will cause 661 * @return #MHD_YES on success, #MHD_NO on failure (will cause
660 * connection to be closed) 662 * connection to be closed)
661 */ 663 */
662// FIXME: This function will need to be called at the right place(s)
663// in the connection processing (just after we are done sending the header)
664// (for responses that have the 'upgrade_header' callback set).
665int 664int
666MHD_response_execute_upgrade_ (struct MHD_Response *response, 665MHD_response_execute_upgrade_ (struct MHD_Response *response,
667 struct MHD_Connection *connection) 666 struct MHD_Connection *connection)
@@ -674,7 +673,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
674 if (NULL == urh) 673 if (NULL == urh)
675 return MHD_NO; 674 return MHD_NO;
676#if HTTPS_SUPPORT 675#if HTTPS_SUPPORT
677 if (0 != (connection->daemon->flags & MHD_USE_SSL) ) 676 if (0 != (connection->daemon->options & MHD_USE_SSL) )
678 { 677 {
679 /* FIXME: this is non-portable for now; W32 port pending... */ 678 /* FIXME: this is non-portable for now; W32 port pending... */
680 if (0 != socketpair (AF_UNIX, 679 if (0 != socketpair (AF_UNIX,
@@ -694,12 +693,12 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
694 connection, 693 connection,
695 connection->read_buffer, 694 connection->read_buffer,
696 rbo, 695 rbo,
697 urh->app_sock, 696 urh->app_socket,
698 urh); 697 urh);
699 /* As far as MHD is concerned, this connection is 698 /* As far as MHD is concerned, this connection is
700 suspended; it will be resumed once we are done 699 suspended; it will be resumed once we are done
701 in the #MHD_upgrade_action() function */ 700 in the #MHD_upgrade_action() function */
702 MHD_connection_suspend (connection); 701 MHD_suspend_connection (connection);
703 /* FIXME: also need to start some processing logic in _all_ MHD 702 /* FIXME: also need to start some processing logic in _all_ MHD
704 event loops for the sv traffic! (NOT IMPLEMENTED!!!) */ 703 event loops for the sv traffic! (NOT IMPLEMENTED!!!) */
705 return MHD_YES; 704 return MHD_YES;
@@ -718,7 +717,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
718 /* As far as MHD is concerned, this connection is 717 /* As far as MHD is concerned, this connection is
719 suspended; it will be resumed once we are done 718 suspended; it will be resumed once we are done
720 in the #MHD_upgrade_action() function */ 719 in the #MHD_upgrade_action() function */
721 MHD_connection_suspend (connection); 720 MHD_suspend_connection (connection);
722 return MHD_YES; 721 return MHD_YES;
723} 722}
724 723
@@ -758,7 +757,7 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
758{ 757{
759 struct MHD_Response *response; 758 struct MHD_Response *response;
760 759
761 if (NULL == upgrade_header) 760 if (NULL == upgrade_handler)
762 return NULL; /* invalid request */ 761 return NULL; /* invalid request */
763 response = malloc (sizeof (struct MHD_Response)); 762 response = malloc (sizeof (struct MHD_Response));
764 if (NULL == response) 763 if (NULL == response)
@@ -769,14 +768,12 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
769 free (response); 768 free (response);
770 return NULL; 769 return NULL;
771 } 770 }
772 urh->response = response;
773 response->upgrade_handler = upgrade_handler; 771 response->upgrade_handler = upgrade_handler;
774 response->upgrade_handler_cls = upgrade_handler_cls; 772 response->upgrade_handler_cls = upgrade_handler_cls;
775 response->total_size = MHD_SIZE_UNKNOWN; 773 response->total_size = MHD_SIZE_UNKNOWN;
776 response->reference_count = 1; 774 response->reference_count = 1;
777 return response; 775 return response;
778} 776}
779#endif
780 777
781 778
782/** 779/**
diff --git a/src/microhttpd/response.h b/src/microhttpd/response.h
index a13683d1..ce7e131c 100644
--- a/src/microhttpd/response.h
+++ b/src/microhttpd/response.h
@@ -36,4 +36,22 @@ void
36MHD_increment_response_rc (struct MHD_Response *response); 36MHD_increment_response_rc (struct MHD_Response *response);
37 37
38 38
39/**
40 * We are done sending the header of a given response
41 * to the client. Now it is time to perform the upgrade
42 * and hand over the connection to the application.
43 *
44 * @param response the response that was created for an upgrade
45 * @param connection the specific connection we are upgrading
46 * @return #MHD_YES on success, #MHD_NO on failure (will cause
47 * connection to be closed)
48 */
49// FIXME: This function will need to be called at the right place(s)
50// in the connection processing (just after we are done sending the header)
51// (for responses that have the 'upgrade_header' callback set).
52int
53MHD_response_execute_upgrade_ (struct MHD_Response *response,
54 struct MHD_Connection *connection);
55
56
39#endif 57#endif