aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/response.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r--src/microhttpd/response.c97
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,