aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 62cd3ce8..08709c80 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -883,6 +883,61 @@ call_handlers (struct MHD_Connection *con,
883 883
884#if HTTPS_SUPPORT 884#if HTTPS_SUPPORT
885/** 885/**
886 * This function finishes the process of closing the
887 * connection associated with the @a urh. It should
888 * be called if the `was_closed` flag is set and the
889 * buffer has been drained.
890 *
891 * @param urh handle to the upgraded response we are finished with
892 */
893static void
894finish_upgrade_close (struct MHD_UpgradeResponseHandle *urh)
895{
896 struct MHD_Connection *connection = urh->connection;
897 struct MHD_Daemon *daemon = connection->daemon;
898
899 DLL_remove (daemon->urh_head,
900 daemon->urh_tail,
901 urh);
902 if (0 != (daemon->options & MHD_USE_EPOLL))
903 {
904 /* epoll documentation suggests that closing a FD
905 automatically removes it from the epoll set; however,
906 this is not true as if we fail to do manually remove it,
907 we are still seeing an event for this fd in epoll,
908 causing grief (use-after-free...) --- at least on my
909 system. */
910 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
911 EPOLL_CTL_DEL,
912 connection->socket_fd,
913 NULL))
914 MHD_PANIC ("Failed to remove FD from epoll set\n");
915 }
916 if (MHD_INVALID_SOCKET != urh->mhd.socket)
917 {
918 /* epoll documentation suggests that closing a FD
919 automatically removes it from the epoll set; however,
920 this is not true as if we fail to do manually remove it,
921 we are still seeing an event for this fd in epoll,
922 causing grief (use-after-free...) --- at least on my
923 system. */
924 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
925 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
926 EPOLL_CTL_DEL,
927 urh->mhd.socket,
928 NULL)) )
929 MHD_PANIC ("Failed to remove FD from epoll set\n");
930 if (0 != MHD_socket_close_ (urh->mhd.socket))
931 MHD_PANIC ("close failed\n");
932 }
933 MHD_resume_connection (connection);
934 MHD_connection_close_ (connection,
935 MHD_REQUEST_TERMINATED_COMPLETED_OK);
936 free (urh);
937}
938
939
940/**
886 * Performs bi-directional forwarding on upgraded HTTPS connections 941 * Performs bi-directional forwarding on upgraded HTTPS connections
887 * based on the readyness state stored in the @a urh handle. 942 * based on the readyness state stored in the @a urh handle.
888 * 943 *
@@ -891,6 +946,8 @@ call_handlers (struct MHD_Connection *con,
891static void 946static void
892process_urh (struct MHD_UpgradeResponseHandle *urh) 947process_urh (struct MHD_UpgradeResponseHandle *urh)
893{ 948{
949 int fin_read;
950
894 /* handle reading from TLS client and writing to application */ 951 /* handle reading from TLS client and writing to application */
895 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) && 952 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
896 (urh->in_buffer_off < urh->in_buffer_size) ) 953 (urh->in_buffer_off < urh->in_buffer_size) )
@@ -957,7 +1014,10 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
957 { 1014 {
958 urh->out_buffer_off += res; 1015 urh->out_buffer_off += res;
959 } 1016 }
1017 fin_read = (0 == res);
960 } 1018 }
1019 else
1020 fin_read = 0;
961 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 1021 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
962 (urh->out_buffer_off > 0) ) 1022 (urh->out_buffer_off > 0) )
963 { 1023 {
@@ -986,6 +1046,10 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
986 } 1046 }
987 } 1047 }
988 } 1048 }
1049 if ( (fin_read) &&
1050 (0 == urh->out_buffer_off) &&
1051 (MHD_YES == urh->was_closed) )
1052 finish_upgrade_close (urh);
989} 1053}
990#endif 1054#endif
991 1055