aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-28 09:05:57 +0000
committerChristian Grothoff <christian@grothoff.org>2016-08-28 09:05:57 +0000
commit642fef8a5b2a4913bd8a97faea0fd227652c9f31 (patch)
tree4e5aa7632c9b9ae6364b6ef950a3aae73d414376
parentfd7feaf9161ae725d3dab83794b60d56d02be735 (diff)
downloadlibmicrohttpd-642fef8a5b2a4913bd8a97faea0fd227652c9f31.tar.gz
libmicrohttpd-642fef8a5b2a4913bd8a97faea0fd227652c9f31.zip
-fix misc issues with upgrade introduction
-rw-r--r--src/microhttpd/connection.c2
-rw-r--r--src/microhttpd/daemon.c99
-rw-r--r--src/microhttpd/internal.h31
-rw-r--r--src/microhttpd/response.c42
4 files changed, 133 insertions, 41 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 739f3c0f..d5ae884b 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.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-2015 Daniel Pittman and Christian Grothoff 3 Copyright (C) 2007-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
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 3afeda69..79e8ab70 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -654,14 +654,15 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
654 unsigned int fd_setsize) 654 unsigned int fd_setsize)
655{ 655{
656 struct MHD_Connection *pos; 656 struct MHD_Connection *pos;
657 struct MHD_UpgradeResponseHandle *urh;
657 int result = MHD_YES; 658 int result = MHD_YES;
658 659
659 if ( (NULL == daemon) 660 if ( (NULL == daemon) ||
660 || (NULL == read_fd_set) 661 (NULL == read_fd_set) ||
661 || (NULL == write_fd_set) 662 (NULL == write_fd_set) ||
662 || (MHD_YES == daemon->shutdown) 663 (MHD_YES == daemon->shutdown) ||
663 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 664 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
664 || (0 != (daemon->options & MHD_USE_POLL))) 665 (0 != (daemon->options & MHD_USE_POLL)))
665 return MHD_NO; 666 return MHD_NO;
666#ifdef EPOLL_SUPPORT 667#ifdef EPOLL_SUPPORT
667 if (0 != (daemon->options & MHD_USE_EPOLL)) 668 if (0 != (daemon->options & MHD_USE_EPOLL))
@@ -669,11 +670,17 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
669 /* we're in epoll mode, use the epoll FD as a stand-in for 670 /* we're in epoll mode, use the epoll FD as a stand-in for
670 the entire event set */ 671 the entire event set */
671 672
672 return MHD_add_to_fd_set_ (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize) ? MHD_YES : MHD_NO; 673 return MHD_add_to_fd_set_ (daemon->epoll_fd,
674 read_fd_set,
675 max_fd,
676 fd_setsize) ? MHD_YES : MHD_NO;
673 } 677 }
674#endif 678#endif
675 if (MHD_INVALID_SOCKET != daemon->socket_fd && 679 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
676 !MHD_add_to_fd_set_ (daemon->socket_fd, read_fd_set, max_fd, fd_setsize)) 680 (! MHD_add_to_fd_set_ (daemon->socket_fd,
681 read_fd_set,
682 max_fd,
683 fd_setsize)) )
677 result = MHD_NO; 684 result = MHD_NO;
678 685
679 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 686 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
@@ -681,19 +688,31 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
681 switch (pos->event_loop_info) 688 switch (pos->event_loop_info)
682 { 689 {
683 case MHD_EVENT_LOOP_INFO_READ: 690 case MHD_EVENT_LOOP_INFO_READ:
684 if (!MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 691 if (! MHD_add_to_fd_set_ (pos->socket_fd,
692 read_fd_set,
693 max_fd,
694 fd_setsize))
685 result = MHD_NO; 695 result = MHD_NO;
686 break; 696 break;
687 case MHD_EVENT_LOOP_INFO_WRITE: 697 case MHD_EVENT_LOOP_INFO_WRITE:
688 if (!MHD_add_to_fd_set_ (pos->socket_fd, write_fd_set, max_fd, fd_setsize)) 698 if (! MHD_add_to_fd_set_ (pos->socket_fd,
699 write_fd_set,
700 max_fd,
701 fd_setsize))
689 result = MHD_NO; 702 result = MHD_NO;
690 if (pos->read_buffer_size > pos->read_buffer_offset && 703 if ( (pos->read_buffer_size > pos->read_buffer_offset) &&
691 !MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 704 ! MHD_add_to_fd_set_ (pos->socket_fd,
705 read_fd_set,
706 max_fd,
707 fd_setsize))
692 result = MHD_NO; 708 result = MHD_NO;
693 break; 709 break;
694 case MHD_EVENT_LOOP_INFO_BLOCK: 710 case MHD_EVENT_LOOP_INFO_BLOCK:
695 if (pos->read_buffer_size > pos->read_buffer_offset && 711 if ( (pos->read_buffer_size > pos->read_buffer_offset) &&
696 !MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 712 ! MHD_add_to_fd_set_ (pos->socket_fd,
713 read_fd_set,
714 max_fd,
715 fd_setsize))
697 result = MHD_NO; 716 result = MHD_NO;
698 break; 717 break;
699 case MHD_EVENT_LOOP_INFO_CLEANUP: 718 case MHD_EVENT_LOOP_INFO_CLEANUP:
@@ -701,6 +720,33 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
701 break; 720 break;
702 } 721 }
703 } 722 }
723 for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
724 {
725 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) &&
726 (! MHD_add_to_fd_set_ (urh->mhd_socket,
727 read_fd_set,
728 max_fd,
729 fd_setsize)) )
730 result = MHD_NO;
731 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) &&
732 (! MHD_add_to_fd_set_ (urh->mhd_socket,
733 write_fd_set,
734 max_fd,
735 fd_setsize)) )
736 result = MHD_NO;
737 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) &&
738 (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
739 read_fd_set,
740 max_fd,
741 fd_setsize)) )
742 result = MHD_NO;
743 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) &&
744 (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
745 write_fd_set,
746 max_fd,
747 fd_setsize)) )
748 result = MHD_NO;
749 }
704#if DEBUG_CONNECT 750#if DEBUG_CONNECT
705#ifdef HAVE_MESSAGES 751#ifdef HAVE_MESSAGES
706 if (NULL != max_fd) 752 if (NULL != max_fd)
@@ -714,9 +760,8 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
714 760
715 761
716/** 762/**
717 * Call the handlers for a connection in the 763 * Call the handlers for a connection in the appropriate order based
718 * appropriate order based on the readiness as 764 * on the readiness as detected by the event loop.
719 * detected by the event loop.
720 * 765 *
721 * @param con connection to handle 766 * @param con connection to handle
722 * @param read_ready set if the socket is ready for reading 767 * @param read_ready set if the socket is ready for reading
@@ -1239,7 +1284,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1239 return MHD_NO; 1284 return MHD_NO;
1240 } 1285 }
1241 1286
1242 if ( (!MHD_SCKT_FD_FITS_FDSET_(client_socket, NULL)) && 1287 if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, NULL)) &&
1243 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) 1288 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
1244 { 1289 {
1245#ifdef HAVE_MESSAGES 1290#ifdef HAVE_MESSAGES
@@ -1791,7 +1836,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1791 already set in MHD_USE_EPOLL_TURBO mode */ 1836 already set in MHD_USE_EPOLL_TURBO mode */
1792 if (0 != (daemon->options & MHD_USE_EPOLL_TURBO)) 1837 if (0 != (daemon->options & MHD_USE_EPOLL_TURBO))
1793 { 1838 {
1794 if (!MHD_socket_nonblocking_ (client_socket)) 1839 if (! MHD_socket_nonblocking_ (client_socket))
1795 { 1840 {
1796#ifdef HAVE_MESSAGES 1841#ifdef HAVE_MESSAGES
1797 MHD_DLOG (daemon, 1842 MHD_DLOG (daemon,
@@ -1799,7 +1844,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1799 MHD_socket_last_strerr_()); 1844 MHD_socket_last_strerr_());
1800#endif 1845#endif
1801 } 1846 }
1802 if (!MHD_socket_noninheritable_ (client_socket)) 1847 if (! MHD_socket_noninheritable_ (client_socket))
1803 { 1848 {
1804#ifdef HAVE_MESSAGES 1849#ifdef HAVE_MESSAGES
1805 MHD_DLOG (daemon, 1850 MHD_DLOG (daemon,
@@ -1858,7 +1903,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1858 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) 1903 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err))
1859 return MHD_NO; /* do not print error if client just disconnected early */ 1904 return MHD_NO; /* do not print error if client just disconnected early */
1860#ifdef HAVE_MESSAGES 1905#ifdef HAVE_MESSAGES
1861 if ( !MHD_SCKT_ERR_IS_EAGAIN_ (err) ) 1906 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
1862 MHD_DLOG (daemon, 1907 MHD_DLOG (daemon,
1863 "Error accepting connection: %s\n", 1908 "Error accepting connection: %s\n",
1864 MHD_socket_strerr_(err)); 1909 MHD_socket_strerr_(err));
@@ -1895,7 +1940,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1895 return MHD_NO; 1940 return MHD_NO;
1896 } 1941 }
1897#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 1942#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
1898 if (!MHD_socket_nonblocking_ (s)) 1943 if (! MHD_socket_nonblocking_ (s))
1899 { 1944 {
1900#ifdef HAVE_MESSAGES 1945#ifdef HAVE_MESSAGES
1901 MHD_DLOG (daemon, 1946 MHD_DLOG (daemon,
@@ -1905,7 +1950,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1905 } 1950 }
1906#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ 1951#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
1907#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 1952#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
1908 if (!MHD_socket_noninheritable_ (s)) 1953 if (! MHD_socket_noninheritable_ (s))
1909 { 1954 {
1910#ifdef HAVE_MESSAGES 1955#ifdef HAVE_MESSAGES
1911 MHD_DLOG (daemon, 1956 MHD_DLOG (daemon,
@@ -1920,8 +1965,10 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1920 s); 1965 s);
1921#endif 1966#endif
1922#endif 1967#endif
1923 (void) internal_add_connection (daemon, s, 1968 (void) internal_add_connection (daemon,
1924 addr, addrlen, 1969 s,
1970 addr,
1971 addrlen,
1925 MHD_NO); 1972 MHD_NO);
1926 return MHD_YES; 1973 return MHD_YES;
1927} 1974}
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index c1524330..047300b1 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -147,22 +147,22 @@ enum MHD_ConnectionEventLoopInfo
147 /** 147 /**
148 * We are waiting to be able to read. 148 * We are waiting to be able to read.
149 */ 149 */
150 MHD_EVENT_LOOP_INFO_READ = 1, 150 MHD_EVENT_LOOP_INFO_READ = 0,
151 151
152 /** 152 /**
153 * We are waiting to be able to write. 153 * We are waiting to be able to write.
154 */ 154 */
155 MHD_EVENT_LOOP_INFO_WRITE = 2, 155 MHD_EVENT_LOOP_INFO_WRITE = 1,
156 156
157 /** 157 /**
158 * We are waiting for the application to provide data. 158 * We are waiting for the application to provide data.
159 */ 159 */
160 MHD_EVENT_LOOP_INFO_BLOCK = 4, 160 MHD_EVENT_LOOP_INFO_BLOCK = 2,
161 161
162 /** 162 /**
163 * We are finished and are awaiting cleanup. 163 * We are finished and are awaiting cleanup.
164 */ 164 */
165 MHD_EVENT_LOOP_INFO_CLEANUP = 8 165 MHD_EVENT_LOOP_INFO_CLEANUP = 3
166}; 166};
167 167
168 168
@@ -918,11 +918,6 @@ struct MHD_UpgradeResponseHandle
918 MHD_socket app_socket; 918 MHD_socket app_socket;
919 919
920 /** 920 /**
921 * IO-state of the @e app_socket.
922 */
923 enum MHD_ConnectionEventLoopInfo celi_app;
924
925 /**
926 * If @a app_sock was a socketpair, our end of it, otherwise 921 * If @a app_sock was a socketpair, our end of it, otherwise
927 * #MHD_INVALID_SOCKET; (r/w). 922 * #MHD_INVALID_SOCKET; (r/w).
928 */ 923 */
@@ -931,7 +926,13 @@ struct MHD_UpgradeResponseHandle
931 /** 926 /**
932 * IO-state of the @e mhd_socket. 927 * IO-state of the @e mhd_socket.
933 */ 928 */
934 enum MHD_ConnectionEventLoopInfo celi_mhd; 929 enum MHD_EpollState celi_mhd;
930
931 /**
932 * IO-state of the @e connection's socket.
933 */
934 enum MHD_EpollState celi_client;
935
935 936
936}; 937};
937 938
@@ -1027,6 +1028,16 @@ struct MHD_Daemon
1027#endif 1028#endif
1028 1029
1029 /** 1030 /**
1031 * Head of DLL of upgrade response handles we are processing.
1032 */
1033 struct MHD_UpgradeResponseHandle *urh_head;
1034
1035 /**
1036 * Tail of DLL of upgrade response handles we are processing.
1037 */
1038 struct MHD_UpgradeResponseHandle *urh_tail;
1039
1040 /**
1030 * Head of the XDLL of ALL connections with a default ('normal') 1041 * Head of the XDLL of ALL connections with a default ('normal')
1031 * timeout, sorted by timeout (earliest at the tail, most recently 1042 * timeout, sorted by timeout (earliest at the tail, most recently
1032 * used connection at the head). MHD can just look at the tail of 1043 * used connection at the head). MHD can just look at the tail of
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index e7049a5a..93803813 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -597,10 +597,20 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
597 enum MHD_UpgradeAction action, 597 enum MHD_UpgradeAction action,
598 ...) 598 ...)
599{ 599{
600 struct MHD_Daemon *daemon = urh->connection->daemon;
601
600 switch (action) 602 switch (action)
601 { 603 {
602 case MHD_UPGRADE_ACTION_CLOSE: 604 case MHD_UPGRADE_ACTION_CLOSE:
603 /* Application is done with this connection, tear it down! */ 605 /* Application is done with this connection, tear it down! */
606 if (0 != (daemon->options & MHD_USE_SSL) )
607 {
608 DLL_remove (daemon->urh_head,
609 daemon->urh_tail,
610 urh);
611 /* FIXME: if running in epoll()-mode, do we have
612 to remove any of the FDs from any epoll-sets here? */
613 }
604 if ( (MHD_INVALID_SOCKET != urh->app_socket) && 614 if ( (MHD_INVALID_SOCKET != urh->app_socket) &&
605 (0 != MHD_socket_close_ (urh->app_socket)) ) 615 (0 != MHD_socket_close_ (urh->app_socket)) )
606 MHD_PANIC ("close failed\n"); 616 MHD_PANIC ("close failed\n");
@@ -636,6 +646,7 @@ int
636MHD_response_execute_upgrade_ (struct MHD_Response *response, 646MHD_response_execute_upgrade_ (struct MHD_Response *response,
637 struct MHD_Connection *connection) 647 struct MHD_Connection *connection)
638{ 648{
649 struct MHD_Daemon *daemon = connection->daemon;
639 struct MHD_UpgradeResponseHandle *urh; 650 struct MHD_UpgradeResponseHandle *urh;
640 int sv[2]; 651 int sv[2];
641 size_t rbo; 652 size_t rbo;
@@ -645,7 +656,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
645 MHD_HTTP_HEADER_UPGRADE)) 656 MHD_HTTP_HEADER_UPGRADE))
646 { 657 {
647#ifdef HAVE_MESSAGES 658#ifdef HAVE_MESSAGES
648 MHD_DLOG (connection->daemon, 659 MHD_DLOG (daemon,
649 "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"); 660 "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n");
650#endif 661#endif
651 return MHD_NO; 662 return MHD_NO;
@@ -655,7 +666,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
655 if (NULL == urh) 666 if (NULL == urh)
656 return MHD_NO; 667 return MHD_NO;
657#if HTTPS_SUPPORT 668#if HTTPS_SUPPORT
658 if (0 != (connection->daemon->options & MHD_USE_SSL) ) 669 if (0 != (daemon->options & MHD_USE_SSL) )
659 { 670 {
660 /* FIXME: this is non-portable for now; W32 port pending... */ 671 /* FIXME: this is non-portable for now; W32 port pending... */
661 if (0 != socketpair (AF_UNIX, 672 if (0 != socketpair (AF_UNIX,
@@ -666,6 +677,23 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
666 free (urh); 677 free (urh);
667 return MHD_NO; 678 return MHD_NO;
668 } 679 }
680 if ( (! MHD_SCKT_FD_FITS_FDSET_(sv[1], NULL)) &&
681 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
682 {
683#ifdef HAVE_MESSAGES
684 MHD_DLOG (daemon,
685 "Socketpair descriptor larger than FD_SETSIZE: %d > %d\n",
686 (int) sv[1],
687 (int) FD_SETSIZE);
688#endif
689 if (0 != MHD_socket_close_ (sv[0]))
690 MHD_PANIC ("close failed\n");
691 if (0 != MHD_socket_close_ (sv[1]))
692 MHD_PANIC ("close failed\n");
693 free (urh);
694 return MHD_NO;
695 }
696
669 urh->app_socket = sv[0]; 697 urh->app_socket = sv[0];
670 urh->mhd_socket = sv[1]; 698 urh->mhd_socket = sv[1];
671 urh->connection = connection; 699 urh->connection = connection;
@@ -682,8 +710,14 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
682 suspended; it will be resumed once we are done 710 suspended; it will be resumed once we are done
683 in the #MHD_upgrade_action() function */ 711 in the #MHD_upgrade_action() function */
684 MHD_suspend_connection (connection); 712 MHD_suspend_connection (connection);
685 /* FIXME: also need to start some processing logic in _all_ MHD 713 urh->celi_mhd = MHD_EPOLL_STATE_UNREADY;
686 event loops for the sv traffic! (NOT IMPLEMENTED!!!) */ 714 urh->celi_client = MHD_EPOLL_STATE_UNREADY;
715 /* FIXME: is it possible we did not fully drain the client
716 socket yet and are thus read-ready already? This may
717 matter if we are in epoll() edge triggered mode... */
718 DLL_insert (connection->daemon->urh_head,
719 connection->daemon->urh_tail,
720 urh);
687 return MHD_YES; 721 return MHD_YES;
688 } 722 }
689#endif 723#endif