diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 250 |
1 files changed, 127 insertions, 123 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 929a76ba..5351b621 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -635,6 +635,7 @@ MHD_get_fdset (struct MHD_Daemon *daemon, | |||
635 | } | 635 | } |
636 | 636 | ||
637 | 637 | ||
638 | #if HTTPS_SUPPORT | ||
638 | /** | 639 | /** |
639 | * Obtain the select() file descriptor sets for the | 640 | * Obtain the select() file descriptor sets for the |
640 | * given @a urh. | 641 | * given @a urh. |
@@ -710,6 +711,7 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
710 | ws)) | 711 | ws)) |
711 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 712 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
712 | } | 713 | } |
714 | #endif | ||
713 | 715 | ||
714 | 716 | ||
715 | /** | 717 | /** |
@@ -742,7 +744,6 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
742 | unsigned int fd_setsize) | 744 | unsigned int fd_setsize) |
743 | { | 745 | { |
744 | struct MHD_Connection *pos; | 746 | struct MHD_Connection *pos; |
745 | struct MHD_UpgradeResponseHandle *urh; | ||
746 | int result = MHD_YES; | 747 | int result = MHD_YES; |
747 | 748 | ||
748 | if ( (NULL == daemon) || | 749 | if ( (NULL == daemon) || |
@@ -808,16 +809,22 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
808 | break; | 809 | break; |
809 | } | 810 | } |
810 | } | 811 | } |
811 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) | 812 | #if HTTPS_SUPPORT |
812 | { | 813 | { |
813 | if (MHD_NO == | 814 | struct MHD_UpgradeResponseHandle *urh; |
814 | urh_to_fdset (urh, | 815 | |
815 | read_fd_set, | 816 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) |
816 | write_fd_set, | 817 | { |
817 | max_fd, | 818 | if (MHD_NO == |
818 | fd_setsize)) | 819 | urh_to_fdset (urh, |
819 | result = MHD_NO; | 820 | read_fd_set, |
820 | } | 821 | write_fd_set, |
822 | max_fd, | ||
823 | fd_setsize)) | ||
824 | result = MHD_NO; | ||
825 | } | ||
826 | } | ||
827 | #endif | ||
821 | #if DEBUG_CONNECT | 828 | #if DEBUG_CONNECT |
822 | #ifdef HAVE_MESSAGES | 829 | #ifdef HAVE_MESSAGES |
823 | if (NULL != max_fd) | 830 | if (NULL != max_fd) |
@@ -1096,132 +1103,127 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1096 | static void | 1103 | static void |
1097 | thread_main_connection_upgrade (struct MHD_Connection *con) | 1104 | thread_main_connection_upgrade (struct MHD_Connection *con) |
1098 | { | 1105 | { |
1099 | struct MHD_Daemon *daemon = con->daemon; | ||
1100 | struct MHD_UpgradeResponseHandle *urh = con->urh; | 1106 | struct MHD_UpgradeResponseHandle *urh = con->urh; |
1101 | |||
1102 | #if HTTPS_SUPPORT | 1107 | #if HTTPS_SUPPORT |
1103 | { | 1108 | struct MHD_Daemon *daemon = con->daemon; |
1104 | /* Here, we need to bi-directionally forward | 1109 | |
1105 | until the application tells us that it is done | 1110 | /* Here, we need to bi-directionally forward |
1106 | with the socket; */ | 1111 | until the application tells us that it is done |
1107 | if (0 == (daemon->options & MHD_USE_POLL)) | 1112 | with the socket; */ |
1108 | { | 1113 | if (0 == (daemon->options & MHD_USE_POLL)) |
1109 | while (MHD_CONNECTION_UPGRADE == con->state) | 1114 | { |
1110 | { | 1115 | while (MHD_CONNECTION_UPGRADE == con->state) |
1111 | /* use select */ | 1116 | { |
1112 | fd_set rs; | 1117 | /* use select */ |
1113 | fd_set ws; | 1118 | fd_set rs; |
1114 | MHD_socket max_fd; | 1119 | fd_set ws; |
1115 | int num_ready; | 1120 | MHD_socket max_fd; |
1116 | int result; | 1121 | int num_ready; |
1117 | 1122 | int result; | |
1118 | FD_ZERO (&rs); | 1123 | |
1119 | FD_ZERO (&ws); | 1124 | FD_ZERO (&rs); |
1120 | max_fd = MHD_INVALID_SOCKET; | 1125 | FD_ZERO (&ws); |
1121 | result = urh_to_fdset (urh, | 1126 | max_fd = MHD_INVALID_SOCKET; |
1122 | &rs, | 1127 | result = urh_to_fdset (urh, |
1123 | &ws, | 1128 | &rs, |
1124 | &max_fd, | 1129 | &ws, |
1125 | FD_SETSIZE); | 1130 | &max_fd, |
1126 | if (MHD_NO == result) | 1131 | FD_SETSIZE); |
1127 | { | 1132 | if (MHD_NO == result) |
1133 | { | ||
1128 | #ifdef HAVE_MESSAGES | 1134 | #ifdef HAVE_MESSAGES |
1129 | MHD_DLOG (con->daemon, | 1135 | MHD_DLOG (con->daemon, |
1130 | "Error preparing select\n"); | 1136 | "Error preparing select\n"); |
1131 | #endif | 1137 | #endif |
1132 | break; | 1138 | break; |
1133 | } | 1139 | } |
1134 | if (MHD_INVALID_SOCKET != max_fd) | 1140 | if (MHD_INVALID_SOCKET != max_fd) |
1135 | num_ready = MHD_SYS_select_ (max_fd + 1, | 1141 | num_ready = MHD_SYS_select_ (max_fd + 1, |
1136 | &rs, | 1142 | &rs, |
1137 | &ws, | 1143 | &ws, |
1138 | NULL, | 1144 | NULL, |
1139 | NULL); | 1145 | NULL); |
1140 | else | 1146 | else |
1141 | num_ready = 0; | 1147 | num_ready = 0; |
1142 | if (num_ready < 0) | 1148 | if (num_ready < 0) |
1143 | { | 1149 | { |
1144 | const int err = MHD_socket_get_error_(); | 1150 | const int err = MHD_socket_get_error_(); |
1145 | 1151 | ||
1146 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 1152 | if (MHD_SCKT_ERR_IS_EINTR_(err)) |
1147 | continue; | 1153 | continue; |
1148 | #ifdef HAVE_MESSAGES | 1154 | #ifdef HAVE_MESSAGES |
1149 | MHD_DLOG (con->daemon, | 1155 | MHD_DLOG (con->daemon, |
1150 | "Error during select (%d): `%s'\n", | 1156 | "Error during select (%d): `%s'\n", |
1151 | err, | 1157 | err, |
1152 | MHD_socket_strerr_ (err)); | 1158 | MHD_socket_strerr_ (err)); |
1153 | #endif | 1159 | #endif |
1154 | break; | 1160 | break; |
1155 | } | 1161 | } |
1156 | urh_from_fdset (urh, | 1162 | urh_from_fdset (urh, |
1157 | &rs, | 1163 | &rs, |
1158 | &ws); | 1164 | &ws); |
1159 | process_urh (urh); | 1165 | process_urh (urh); |
1160 | if ( (0 == urh->out_buffer_size) && | 1166 | if ( (0 == urh->out_buffer_size) && |
1161 | (0 == urh->in_buffer_size) ) | 1167 | (0 == urh->in_buffer_size) ) |
1162 | break; /* connections died, we have no more purpose here */ | 1168 | break; /* connections died, we have no more purpose here */ |
1163 | } | 1169 | } |
1164 | } | 1170 | } |
1165 | #ifdef HAVE_POLL | 1171 | #ifdef HAVE_POLL |
1166 | else | 1172 | else |
1167 | { | 1173 | { |
1168 | /* use poll() */ | 1174 | /* use poll() */ |
1169 | const unsigned int timeout = UINT_MAX; | 1175 | const unsigned int timeout = UINT_MAX; |
1170 | |||
1171 | while (MHD_CONNECTION_UPGRADE == con->state) | ||
1172 | { | ||
1173 | struct pollfd p[2]; | ||
1174 | |||
1175 | memset (p, 0, sizeof (struct pollfd) * 2); | ||
1176 | p[0].fd = urh->connection->socket_fd; | ||
1177 | p[1].fd = urh->mhd.socket; | ||
1178 | if (urh->in_buffer_off < urh->in_buffer_size) | ||
1179 | p[0].events |= POLLIN; | ||
1180 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) | ||
1181 | p[0].events |= POLLOUT; | ||
1182 | if (urh->out_buffer_off < urh->out_buffer_size) | ||
1183 | p[1].events |= POLLIN; | ||
1184 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) | ||
1185 | p[1].events |= POLLOUT; | ||
1186 | 1176 | ||
1187 | if ( (0 != (p[0].events | p[1].events)) && | 1177 | while (MHD_CONNECTION_UPGRADE == con->state) |
1188 | (MHD_sys_poll_ (p, | 1178 | { |
1189 | 2, | 1179 | struct pollfd p[2]; |
1190 | timeout) < 0) ) | 1180 | |
1191 | { | 1181 | memset (p, 0, sizeof (struct pollfd) * 2); |
1192 | const int err = MHD_socket_get_error_ (); | 1182 | p[0].fd = urh->connection->socket_fd; |
1183 | p[1].fd = urh->mhd.socket; | ||
1184 | if (urh->in_buffer_off < urh->in_buffer_size) | ||
1185 | p[0].events |= POLLIN; | ||
1186 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) | ||
1187 | p[0].events |= POLLOUT; | ||
1188 | if (urh->out_buffer_off < urh->out_buffer_size) | ||
1189 | p[1].events |= POLLIN; | ||
1190 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) | ||
1191 | p[1].events |= POLLOUT; | ||
1192 | |||
1193 | if ( (0 != (p[0].events | p[1].events)) && | ||
1194 | (MHD_sys_poll_ (p, | ||
1195 | 2, | ||
1196 | timeout) < 0) ) | ||
1197 | { | ||
1198 | const int err = MHD_socket_get_error_ (); | ||
1193 | 1199 | ||
1194 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 1200 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
1195 | continue; | 1201 | continue; |
1196 | #ifdef HAVE_MESSAGES | 1202 | #ifdef HAVE_MESSAGES |
1197 | MHD_DLOG (con->daemon, | 1203 | MHD_DLOG (con->daemon, |
1198 | "Error during poll: `%s'\n", | 1204 | "Error during poll: `%s'\n", |
1199 | MHD_socket_strerr_ (err)); | 1205 | MHD_socket_strerr_ (err)); |
1200 | #endif | 1206 | #endif |
1201 | break; | 1207 | break; |
1202 | } | 1208 | } |
1203 | if (0 != (p[0].revents & POLLIN)) | 1209 | if (0 != (p[0].revents & POLLIN)) |
1204 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 1210 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
1205 | if (0 != (p[0].revents & POLLOUT)) | 1211 | if (0 != (p[0].revents & POLLOUT)) |
1206 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 1212 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
1207 | if (0 != (p[1].revents & POLLIN)) | 1213 | if (0 != (p[1].revents & POLLIN)) |
1208 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 1214 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
1209 | if (0 != (p[1].revents & POLLOUT)) | 1215 | if (0 != (p[1].revents & POLLOUT)) |
1210 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 1216 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
1211 | process_urh (urh); | 1217 | process_urh (urh); |
1212 | if ( (0 == urh->out_buffer_size) && | 1218 | if ( (0 == urh->out_buffer_size) && |
1213 | (0 == urh->in_buffer_size) ) | 1219 | (0 == urh->in_buffer_size) ) |
1214 | break; /* connections died, we have no more purpose here */ | 1220 | break; /* connections died, we have no more purpose here */ |
1215 | } | 1221 | } |
1216 | } | 1222 | } |
1217 | /* end POLL */ | 1223 | /* end POLL */ |
1218 | #endif | 1224 | #endif |
1219 | /* end HTTPS */ | 1225 | /* end HTTPS */ |
1220 | #else | ||
1221 | /* HTTPS option set, but compiled without HTTPS */ | ||
1222 | MHD_PANIC ("This should not be possible\n"); | ||
1223 | #endif | 1226 | #endif |
1224 | } | ||
1225 | 1227 | ||
1226 | /* Here, we need to block until the application | 1228 | /* Here, we need to block until the application |
1227 | signals us that it is done with the socket */ | 1229 | signals us that it is done with the socket */ |
@@ -4977,6 +4979,7 @@ thread_failed: | |||
4977 | free_and_fail: | 4979 | free_and_fail: |
4978 | /* clean up basic memory state in 'daemon' and return NULL to | 4980 | /* clean up basic memory state in 'daemon' and return NULL to |
4979 | indicate failure */ | 4981 | indicate failure */ |
4982 | #if HTTPS_SUPPORT | ||
4980 | #ifdef EPOLL_SUPPORT | 4983 | #ifdef EPOLL_SUPPORT |
4981 | if (MHD_YES == daemon->upgrade_fd_in_epoll) | 4984 | if (MHD_YES == daemon->upgrade_fd_in_epoll) |
4982 | { | 4985 | { |
@@ -4987,6 +4990,7 @@ thread_failed: | |||
4987 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | 4990 | MHD_PANIC ("Failed to remove FD from epoll set\n"); |
4988 | daemon->upgrade_fd_in_epoll = MHD_NO; | 4991 | daemon->upgrade_fd_in_epoll = MHD_NO; |
4989 | } | 4992 | } |
4993 | #endif | ||
4990 | if (-1 != daemon->epoll_fd) | 4994 | if (-1 != daemon->epoll_fd) |
4991 | close (daemon->epoll_fd); | 4995 | close (daemon->epoll_fd); |
4992 | #if HTTPS_SUPPORT | 4996 | #if HTTPS_SUPPORT |