diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-08-27 18:08:00 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-08-27 18:08:00 +0000 |
commit | e0a43cb194fd22ceaed6905d964f2fcd829b933d (patch) | |
tree | e4ec639adcbc441535cdd6e92a5ac3e5ea0be5b9 | |
parent | 63eb4c75a31654c0b74e2985a0b7861ddaa8d5b3 (diff) | |
download | libmicrohttpd-e0a43cb194fd22ceaed6905d964f2fcd829b933d.tar.gz libmicrohttpd-e0a43cb194fd22ceaed6905d964f2fcd829b933d.zip |
sketching support for upgrade handling
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/include/microhttpd.h | 7 | ||||
-rw-r--r-- | src/microhttpd/connection.c | 33 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 10 | ||||
-rw-r--r-- | src/microhttpd/response.c | 31 | ||||
-rw-r--r-- | src/microhttpd/response.h | 18 |
6 files changed, 75 insertions, 28 deletions
@@ -1,3 +1,7 @@ | |||
1 | Sat Aug 27 20:07:53 CEST 2016 | ||
2 | Adding completely *untested* logic for HTTP "Upgrade" | ||
3 | handling. -CG | ||
4 | |||
1 | Sat Aug 27 18:20:38 CEST 2016 | 5 | Sat 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 * |
2371 | MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, | 2370 | MHD_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). | ||
665 | int | 664 | int |
666 | MHD_response_execute_upgrade_ (struct MHD_Response *response, | 665 | MHD_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 | |||
36 | MHD_increment_response_rc (struct MHD_Response *response); | 36 | MHD_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). | ||
52 | int | ||
53 | MHD_response_execute_upgrade_ (struct MHD_Response *response, | ||
54 | struct MHD_Connection *connection); | ||
55 | |||
56 | |||
39 | #endif | 57 | #endif |