diff options
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r-- | src/microhttpd/response.c | 97 |
1 files changed, 34 insertions, 63 deletions
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c index b0fffe19..db77dc6d 100644 --- a/src/microhttpd/response.c +++ b/src/microhttpd/response.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * @brief Methods for managing response objects | 21 | * @brief Methods for managing response objects |
22 | * @author Daniel Pittman | 22 | * @author Daniel Pittman |
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * @author Karlson2k (Evgeny Grin) | ||
24 | */ | 25 | */ |
25 | 26 | ||
26 | #define MHD_NO_DEPRECATION 1 | 27 | #define MHD_NO_DEPRECATION 1 |
@@ -626,66 +627,41 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, | |||
626 | enum MHD_UpgradeAction action, | 627 | enum MHD_UpgradeAction action, |
627 | ...) | 628 | ...) |
628 | { | 629 | { |
629 | struct MHD_Connection *connection = urh->connection; | 630 | struct MHD_Connection *connection; |
630 | struct MHD_Daemon *daemon = connection->daemon; | 631 | struct MHD_Daemon *daemon; |
632 | if (NULL == urh) | ||
633 | return MHD_NO; | ||
634 | connection = urh->connection; | ||
635 | |||
636 | /* Precaution checks on external data. */ | ||
637 | if (NULL == connection) | ||
638 | return MHD_NO; | ||
639 | daemon = connection->daemon; | ||
640 | if (NULL == daemon) | ||
641 | return MHD_NO; | ||
631 | 642 | ||
632 | switch (action) | 643 | switch (action) |
633 | { | 644 | { |
634 | case MHD_UPGRADE_ACTION_CLOSE: | 645 | case MHD_UPGRADE_ACTION_CLOSE: |
646 | if (MHD_YES == urh->was_closed) | ||
647 | return MHD_NO; /* Already closed. */ | ||
648 | |||
635 | /* transition to special 'closed' state for start of cleanup */ | 649 | /* transition to special 'closed' state for start of cleanup */ |
650 | urh->was_closed = MHD_YES; | ||
636 | connection->state = MHD_CONNECTION_UPGRADE_CLOSED; | 651 | connection->state = MHD_CONNECTION_UPGRADE_CLOSED; |
652 | /* As soon as connection will be marked with BOTH | ||
653 | * 'urh->was_closed' AND 'urh->clean_ready', it will | ||
654 | * be moved to cleanup list by MHD_resume_connection(). */ | ||
655 | MHD_resume_connection (connection); | ||
637 | #if HTTPS_SUPPORT | 656 | #if HTTPS_SUPPORT |
638 | if (0 != (daemon->options & MHD_USE_TLS) ) | 657 | if (0 != (daemon->options & MHD_USE_TLS) ) |
639 | { | 658 | { |
640 | /* signal that app is done by shutdown() of 'app' socket */ | 659 | /* signal that app is done by shutdown() of 'app' socket */ |
660 | /* Application will not use anyway this socket after this command. */ | ||
641 | shutdown (urh->app.socket, | 661 | shutdown (urh->app.socket, |
642 | SHUT_RDWR); | 662 | SHUT_RDWR); |
643 | } | 663 | } |
644 | #endif | 664 | #endif /* HTTPS_SUPPORT */ |
645 | #if HTTPS_SUPPORT | ||
646 | if (0 != (daemon->options & MHD_USE_TLS) ) | ||
647 | { | ||
648 | urh->was_closed = MHD_YES; | ||
649 | /* connection and urh cleanup will be done as soon as outgoing | ||
650 | * data will be sent and 'was_closed' is detected */ | ||
651 | return MHD_YES; | ||
652 | } | ||
653 | #endif | ||
654 | /* Application is done with this connection, tear it down! */ | ||
655 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) | ||
656 | { | ||
657 | /* need to finish connection clean up */ | ||
658 | MHD_cleanup_upgraded_connection_ (connection); | ||
659 | if (MHD_CONNECTION_IN_CLEANUP != connection->state) | ||
660 | { | ||
661 | #if DEBUG_CLOSE | ||
662 | #ifdef HAVE_MESSAGES | ||
663 | MHD_DLOG (connection->daemon, | ||
664 | _("Processing thread terminating. Closing connection\n")); | ||
665 | #endif | ||
666 | #endif | ||
667 | if (MHD_CONNECTION_CLOSED != connection->state) | ||
668 | MHD_connection_close_ (connection, | ||
669 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | ||
670 | connection->idle_handler (connection); | ||
671 | } | ||
672 | if (NULL != connection->response) | ||
673 | { | ||
674 | MHD_destroy_response (connection->response); | ||
675 | connection->response = NULL; | ||
676 | } | ||
677 | |||
678 | if (MHD_INVALID_SOCKET != connection->socket_fd) | ||
679 | { | ||
680 | shutdown (connection->socket_fd, | ||
681 | SHUT_WR); | ||
682 | MHD_socket_close_chk_ (connection->socket_fd); | ||
683 | connection->socket_fd = MHD_INVALID_SOCKET; | ||
684 | } | ||
685 | return MHD_YES; | ||
686 | } | ||
687 | /* 'upgraded' resources are not needed anymore - cleanup now */ | ||
688 | MHD_cleanup_upgraded_connection_ (connection); | ||
689 | return MHD_YES; | 665 | return MHD_YES; |
690 | default: | 666 | default: |
691 | /* we don't understand this one */ | 667 | /* we don't understand this one */ |
@@ -905,30 +881,25 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, | |||
905 | DLL_insert (daemon->urh_head, | 881 | DLL_insert (daemon->urh_head, |
906 | daemon->urh_tail, | 882 | daemon->urh_tail, |
907 | urh); | 883 | urh); |
908 | /* Keep reference for later removal from the DLL */ | ||
909 | connection->urh = urh; | ||
910 | } | 884 | } |
885 | /* In thread-per-connection mode, thread will switch to forwarding once | ||
886 | * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE. | ||
887 | */ | ||
911 | } | 888 | } |
912 | else | 889 | else |
913 | { | 890 | { |
914 | urh->app.socket = MHD_INVALID_SOCKET; | 891 | urh->app.socket = MHD_INVALID_SOCKET; |
915 | urh->mhd.socket = MHD_INVALID_SOCKET; | 892 | urh->mhd.socket = MHD_INVALID_SOCKET; |
893 | /* Non-TLS connection do not hold any additional resources. */ | ||
894 | urh->clean_ready = MHD_YES; | ||
916 | } | 895 | } |
917 | #endif | 896 | #endif |
918 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) | 897 | connection->urh = urh; |
919 | { | 898 | /* As far as MHD's event loops are concerned, this connection is |
920 | /* Our caller will set 'connection->state' to | 899 | suspended; it will be resumed once application is done by the |
921 | MHD_CONNECTION_UPGRADE, thereby triggering the main method | 900 | #MHD_upgrade_action() function */ |
922 | of the thread to switch to bi-directional forwarding or exit. */ | 901 | MHD_suspend_connection (connection); |
923 | connection->urh = urh; | 902 | |
924 | } | ||
925 | else | ||
926 | { | ||
927 | /* As far as MHD's event loops are concerned, this connection is | ||
928 | suspended; it will be resumed once we are done in the | ||
929 | #MHD_upgrade_action() function */ | ||
930 | MHD_suspend_connection (connection); | ||
931 | } | ||
932 | /* hand over socket to application */ | 903 | /* hand over socket to application */ |
933 | response->upgrade_handler (response->upgrade_handler_cls, | 904 | response->upgrade_handler (response->upgrade_handler_cls, |
934 | connection, | 905 | connection, |