diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 236 |
1 files changed, 212 insertions, 24 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 780ba28e..dbf21e18 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -123,7 +123,7 @@ mhd_panic_std (void *cls, | |||
123 | MHD_PanicCallback mhd_panic; | 123 | MHD_PanicCallback mhd_panic; |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * Closure argument for "mhd_panic". | 126 | * Closure argument for #mhd_panic. |
127 | */ | 127 | */ |
128 | void *mhd_panic_cls; | 128 | void *mhd_panic_cls; |
129 | 129 | ||
@@ -401,7 +401,9 @@ MHD_ip_limit_del (struct MHD_Daemon *daemon, | |||
401 | * @return number of bytes actually received | 401 | * @return number of bytes actually received |
402 | */ | 402 | */ |
403 | static ssize_t | 403 | static ssize_t |
404 | recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i) | 404 | recv_tls_adapter (struct MHD_Connection *connection, |
405 | void *other, | ||
406 | size_t i) | ||
405 | { | 407 | { |
406 | ssize_t res; | 408 | ssize_t res; |
407 | 409 | ||
@@ -410,7 +412,9 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i) | |||
410 | connection->daemon->num_tls_read_ready--; | 412 | connection->daemon->num_tls_read_ready--; |
411 | connection->tls_read_ready = MHD_NO; | 413 | connection->tls_read_ready = MHD_NO; |
412 | } | 414 | } |
413 | res = gnutls_record_recv (connection->tls_session, other, i); | 415 | res = gnutls_record_recv (connection->tls_session, |
416 | other, | ||
417 | i); | ||
414 | if ( (GNUTLS_E_AGAIN == res) || | 418 | if ( (GNUTLS_E_AGAIN == res) || |
415 | (GNUTLS_E_INTERRUPTED == res) ) | 419 | (GNUTLS_E_INTERRUPTED == res) ) |
416 | { | 420 | { |
@@ -447,11 +451,14 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i) | |||
447 | */ | 451 | */ |
448 | static ssize_t | 452 | static ssize_t |
449 | send_tls_adapter (struct MHD_Connection *connection, | 453 | send_tls_adapter (struct MHD_Connection *connection, |
450 | const void *other, size_t i) | 454 | const void *other, |
455 | size_t i) | ||
451 | { | 456 | { |
452 | int res; | 457 | int res; |
453 | 458 | ||
454 | res = gnutls_record_send (connection->tls_session, other, i); | 459 | res = gnutls_record_send (connection->tls_session, |
460 | other, | ||
461 | i); | ||
455 | if ( (GNUTLS_E_AGAIN == res) || | 462 | if ( (GNUTLS_E_AGAIN == res) || |
456 | (GNUTLS_E_INTERRUPTED == res) ) | 463 | (GNUTLS_E_INTERRUPTED == res) ) |
457 | { | 464 | { |
@@ -2157,6 +2164,123 @@ MHD_get_timeout (struct MHD_Daemon *daemon, | |||
2157 | } | 2164 | } |
2158 | 2165 | ||
2159 | 2166 | ||
2167 | #if HTTPS_SUPPORT | ||
2168 | /** | ||
2169 | * Performs bi-directional forwarding on upgraded HTTPS connections | ||
2170 | * based on the readyness state stored in the @a urh handle. | ||
2171 | * | ||
2172 | * @param urh handle to process | ||
2173 | */ | ||
2174 | static void | ||
2175 | process_urh (struct MHD_UpgradeResponseHandle *urh) | ||
2176 | { | ||
2177 | #if FIXME_BUFFERS | ||
2178 | // FIXME: we need buffer/buffer_size/buffer_off for | ||
2179 | // both directions to be somehow stored within urh. | ||
2180 | // (Note that despite using the same variable names | ||
2181 | // below, we need actually different buffers for each | ||
2182 | // direction.) | ||
2183 | |||
2184 | /* handle reading from HTTPS client and writing to application */ | ||
2185 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) && | ||
2186 | (buffer_off < buffer_size) ) | ||
2187 | { | ||
2188 | ssize_t res; | ||
2189 | |||
2190 | res = gnutls_record_recv (uri->connection->tls_session, | ||
2191 | &buffer[buffer_off], | ||
2192 | buffer_size - buffer_off); | ||
2193 | if ( (GNUTLS_E_AGAIN == res) || | ||
2194 | (GNUTLS_E_INTERRUPTED == res) ) | ||
2195 | { | ||
2196 | urh->celi_client &= ~MHD_EPOLL_STATE_READ_READY; | ||
2197 | } | ||
2198 | else if (res > 0) | ||
2199 | { | ||
2200 | buffer_off += res; | ||
2201 | } | ||
2202 | } | ||
2203 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) && | ||
2204 | (buffer_off > 0) ) | ||
2205 | { | ||
2206 | size_t res; | ||
2207 | |||
2208 | res = write (urh->mhd_socket, | ||
2209 | buffer, | ||
2210 | buffer_off); | ||
2211 | if (-1 == res) | ||
2212 | { | ||
2213 | /* FIXME: differenciate by errno? */ | ||
2214 | urh->celi_mhd &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
2215 | } | ||
2216 | else | ||
2217 | { | ||
2218 | if (buffer_off != res) | ||
2219 | { | ||
2220 | memmove (buffer, | ||
2221 | &buffer[res], | ||
2222 | buffer_off - res); | ||
2223 | buffer_off -= res; | ||
2224 | } | ||
2225 | else | ||
2226 | { | ||
2227 | buffer_off = 0; | ||
2228 | } | ||
2229 | } | ||
2230 | } | ||
2231 | |||
2232 | /* handle reading from application and writing to HTTPS client */ | ||
2233 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) && | ||
2234 | (buffer_off < buffer_size) ) | ||
2235 | { | ||
2236 | size_t res; | ||
2237 | |||
2238 | res = read (urh->mhd_socket, | ||
2239 | &buffer[buffer_off], | ||
2240 | buffer_size - buffer_off); | ||
2241 | if (-1 == res) | ||
2242 | { | ||
2243 | /* FIXME: differenciate by errno? */ | ||
2244 | urh->celi_mhd &= ~MHD_EPOLL_STATE_READ_READY; | ||
2245 | } | ||
2246 | else | ||
2247 | { | ||
2248 | buffer_off += res; | ||
2249 | } | ||
2250 | } | ||
2251 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) && | ||
2252 | (buffer_off > 0) ) | ||
2253 | { | ||
2254 | ssize_t res; | ||
2255 | |||
2256 | res = gnutls_record_send (uri->connection->tls_session, | ||
2257 | buffer, | ||
2258 | buffer_off); | ||
2259 | if ( (GNUTLS_E_AGAIN == res) || | ||
2260 | (GNUTLS_E_INTERRUPTED == res) ) | ||
2261 | { | ||
2262 | urh->celi_client &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
2263 | } | ||
2264 | else if (res > 0) | ||
2265 | { | ||
2266 | if (buffer_off != res) | ||
2267 | { | ||
2268 | memmove (buffer, | ||
2269 | &buffer[res], | ||
2270 | buffer_off - res); | ||
2271 | buffer_off -= res; | ||
2272 | } | ||
2273 | else | ||
2274 | { | ||
2275 | buffer_off = 0; | ||
2276 | } | ||
2277 | } | ||
2278 | } | ||
2279 | #endif | ||
2280 | } | ||
2281 | #endif | ||
2282 | |||
2283 | |||
2160 | /** | 2284 | /** |
2161 | * Run webserver operations. This method should be called by clients | 2285 | * Run webserver operations. This method should be called by clients |
2162 | * in combination with #MHD_get_fdset if the client-controlled select | 2286 | * in combination with #MHD_get_fdset if the client-controlled select |
@@ -2185,7 +2309,9 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
2185 | MHD_socket ds; | 2309 | MHD_socket ds; |
2186 | struct MHD_Connection *pos; | 2310 | struct MHD_Connection *pos; |
2187 | struct MHD_Connection *next; | 2311 | struct MHD_Connection *next; |
2312 | #if HTTPS_SUPPORT | ||
2188 | struct MHD_UpgradeResponseHandle *urh; | 2313 | struct MHD_UpgradeResponseHandle *urh; |
2314 | #endif | ||
2189 | unsigned int mask = MHD_USE_SUSPEND_RESUME | MHD_USE_EPOLL_INTERNALLY | | 2315 | unsigned int mask = MHD_USE_SUSPEND_RESUME | MHD_USE_EPOLL_INTERNALLY | |
2190 | MHD_USE_SELECT_INTERNALLY | MHD_USE_POLL_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION; | 2316 | MHD_USE_SELECT_INTERNALLY | MHD_USE_POLL_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION; |
2191 | 2317 | ||
@@ -2239,8 +2365,17 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
2239 | #if HTTPS_SUPPORT | 2365 | #if HTTPS_SUPPORT |
2240 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) | 2366 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) |
2241 | { | 2367 | { |
2242 | // if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) && | 2368 | /* update urh state based on select() output */ |
2243 | // (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) ) | 2369 | if (FD_ISSET (urh->connection->socket_fd, read_fd_set)) |
2370 | urh->celi_client |= MHD_EPOLL_STATE_READ_READY; | ||
2371 | if (FD_ISSET (urh->connection->socket_fd, write_fd_set)) | ||
2372 | urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY; | ||
2373 | if (FD_ISSET (urh->mhd_socket, read_fd_set)) | ||
2374 | urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY; | ||
2375 | if (FD_ISSET (urh->mhd_socket, write_fd_set)) | ||
2376 | urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY; | ||
2377 | /* call generic forwarding function for passing data */ | ||
2378 | process_urh (urh); | ||
2244 | } | 2379 | } |
2245 | #endif | 2380 | #endif |
2246 | MHD_cleanup_connections (daemon); | 2381 | MHD_cleanup_connections (daemon); |
@@ -2298,10 +2433,10 @@ MHD_select (struct MHD_Daemon *daemon, | |||
2298 | { | 2433 | { |
2299 | /* accept only, have one thread per connection */ | 2434 | /* accept only, have one thread per connection */ |
2300 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 2435 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && |
2301 | (!MHD_add_to_fd_set_ (daemon->socket_fd, | 2436 | (! MHD_add_to_fd_set_ (daemon->socket_fd, |
2302 | &rs, | 2437 | &rs, |
2303 | &maxsock, | 2438 | &maxsock, |
2304 | FD_SETSIZE)) ) | 2439 | FD_SETSIZE)) ) |
2305 | { | 2440 | { |
2306 | #ifdef HAVE_MESSAGES | 2441 | #ifdef HAVE_MESSAGES |
2307 | MHD_DLOG (daemon, "Could not add listen socket to fdset"); | 2442 | MHD_DLOG (daemon, "Could not add listen socket to fdset"); |
@@ -2310,10 +2445,10 @@ MHD_select (struct MHD_Daemon *daemon, | |||
2310 | } | 2445 | } |
2311 | } | 2446 | } |
2312 | if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && | 2447 | if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && |
2313 | (!MHD_add_to_fd_set_ (daemon->wpipe[0], | 2448 | (! MHD_add_to_fd_set_ (daemon->wpipe[0], |
2314 | &rs, | 2449 | &rs, |
2315 | &maxsock, | 2450 | &maxsock, |
2316 | FD_SETSIZE)) ) | 2451 | FD_SETSIZE)) ) |
2317 | { | 2452 | { |
2318 | #if defined(MHD_WINSOCK_SOCKETS) | 2453 | #if defined(MHD_WINSOCK_SOCKETS) |
2319 | /* fdset limit reached, new connections | 2454 | /* fdset limit reached, new connections |
@@ -2322,10 +2457,10 @@ MHD_select (struct MHD_Daemon *daemon, | |||
2322 | if (MHD_INVALID_SOCKET != daemon->socket_fd) | 2457 | if (MHD_INVALID_SOCKET != daemon->socket_fd) |
2323 | { | 2458 | { |
2324 | FD_CLR (daemon->socket_fd, &rs); | 2459 | FD_CLR (daemon->socket_fd, &rs); |
2325 | if (!MHD_add_to_fd_set_ (daemon->wpipe[0], | 2460 | if (! MHD_add_to_fd_set_ (daemon->wpipe[0], |
2326 | &rs, | 2461 | &rs, |
2327 | &maxsock, | 2462 | &maxsock, |
2328 | FD_SETSIZE)) | 2463 | FD_SETSIZE)) |
2329 | { | 2464 | { |
2330 | #endif /* MHD_WINSOCK_SOCKETS */ | 2465 | #endif /* MHD_WINSOCK_SOCKETS */ |
2331 | #ifdef HAVE_MESSAGES | 2466 | #ifdef HAVE_MESSAGES |
@@ -2410,6 +2545,10 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
2410 | unsigned int num_connections; | 2545 | unsigned int num_connections; |
2411 | struct MHD_Connection *pos; | 2546 | struct MHD_Connection *pos; |
2412 | struct MHD_Connection *next; | 2547 | struct MHD_Connection *next; |
2548 | #if HTTPS_SUPPORT | ||
2549 | struct MHD_UpgradeResponseHandle *urh; | ||
2550 | struct MHD_UpgradeResponseHandle *urhn; | ||
2551 | #endif | ||
2413 | 2552 | ||
2414 | if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) && | 2553 | if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) && |
2415 | (MHD_YES == resume_suspended_connections (daemon)) ) | 2554 | (MHD_YES == resume_suspended_connections (daemon)) ) |
@@ -2419,6 +2558,10 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
2419 | num_connections = 0; | 2558 | num_connections = 0; |
2420 | for (pos = daemon->connections_head; NULL != pos; pos = pos->next) | 2559 | for (pos = daemon->connections_head; NULL != pos; pos = pos->next) |
2421 | num_connections++; | 2560 | num_connections++; |
2561 | #if HTTPS_SUPPORT | ||
2562 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) | ||
2563 | num_connections += 2; | ||
2564 | #endif | ||
2422 | { | 2565 | { |
2423 | MHD_UNSIGNED_LONG_LONG ltimeout; | 2566 | MHD_UNSIGNED_LONG_LONG ltimeout; |
2424 | unsigned int i; | 2567 | unsigned int i; |
@@ -2428,7 +2571,7 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
2428 | int poll_pipe; | 2571 | int poll_pipe; |
2429 | struct pollfd *p; | 2572 | struct pollfd *p; |
2430 | 2573 | ||
2431 | p = malloc(sizeof (struct pollfd) * (2 + num_connections)); | 2574 | p = malloc (sizeof (struct pollfd) * (2 + num_connections)); |
2432 | if (NULL == p) | 2575 | if (NULL == p) |
2433 | { | 2576 | { |
2434 | #ifdef HAVE_MESSAGES | 2577 | #ifdef HAVE_MESSAGES |
@@ -2493,6 +2636,23 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
2493 | } | 2636 | } |
2494 | i++; | 2637 | i++; |
2495 | } | 2638 | } |
2639 | #if HTTPS_SUPPORT | ||
2640 | for (urh = daemon->urh_head; NULL != urh; urh = urh->next) | ||
2641 | { | ||
2642 | p[poll_server+i].fd = urh->connection->socket_fd; | ||
2643 | if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) | ||
2644 | p[poll_server+i].events |= POLLIN; | ||
2645 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) | ||
2646 | p[poll_server+i].events |= POLLOUT; | ||
2647 | i++; | ||
2648 | p[poll_server+i].fd = urh->mhd_socket; | ||
2649 | if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) | ||
2650 | p[poll_server+i].events |= POLLIN; | ||
2651 | if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) | ||
2652 | p[poll_server+i].events |= POLLOUT; | ||
2653 | i++; | ||
2654 | } | ||
2655 | #endif | ||
2496 | if (0 == poll_server + num_connections) | 2656 | if (0 == poll_server + num_connections) |
2497 | { | 2657 | { |
2498 | free(p); | 2658 | free(p); |
@@ -2542,6 +2702,33 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
2542 | 0 != (p[poll_server+i].revents & POLLOUT), | 2702 | 0 != (p[poll_server+i].revents & POLLOUT), |
2543 | MHD_NO); | 2703 | MHD_NO); |
2544 | } | 2704 | } |
2705 | #if HTTPS_SUPPORT | ||
2706 | for (urh = daemon->urh_head; NULL != urh; urh = urhn) | ||
2707 | { | ||
2708 | urhn = urh->next; | ||
2709 | if (p[poll_server+i].fd != urh->connection->socket_fd) | ||
2710 | continue; /* fd mismatch, something else happened, retry later ... */ | ||
2711 | if (0 != (p[poll_server+i].revents & POLLIN)) | ||
2712 | urh->celi_client |= MHD_EPOLL_STATE_READ_READY; | ||
2713 | if (0 != (p[poll_server+i].revents & POLLOUT)) | ||
2714 | urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY; | ||
2715 | i++; | ||
2716 | if (p[poll_server+i].fd != urh->mhd_socket) | ||
2717 | { | ||
2718 | /* fd mismatch, something else happened, retry later ... */ | ||
2719 | /* may still be able to do something based on updates | ||
2720 | to socket_fd availability */ | ||
2721 | process_urh (urh); | ||
2722 | continue; | ||
2723 | } | ||
2724 | if (0 != (p[poll_server+i].revents & POLLIN)) | ||
2725 | urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY; | ||
2726 | if (0 != (p[poll_server+i].revents & POLLOUT)) | ||
2727 | urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY; | ||
2728 | i++; | ||
2729 | process_urh (urh); | ||
2730 | } | ||
2731 | #endif | ||
2545 | /* handle 'listen' FD */ | 2732 | /* handle 'listen' FD */ |
2546 | if ( (-1 != poll_listen) && | 2733 | if ( (-1 != poll_listen) && |
2547 | (0 != (p[poll_listen].revents & POLLIN)) ) | 2734 | (0 != (p[poll_listen].revents & POLLIN)) ) |
@@ -3081,9 +3268,10 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |||
3081 | * @param format format string | 3268 | * @param format format string |
3082 | * @param va arguments to the format string (fprintf-style) | 3269 | * @param va arguments to the format string (fprintf-style) |
3083 | */ | 3270 | */ |
3084 | typedef void (*VfprintfFunctionPointerType)(void *cls, | 3271 | typedef void |
3085 | const char *format, | 3272 | (*VfprintfFunctionPointerType)(void *cls, |
3086 | va_list va); | 3273 | const char *format, |
3274 | va_list va); | ||
3087 | 3275 | ||
3088 | 3276 | ||
3089 | /** | 3277 | /** |
@@ -3687,7 +3875,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
3687 | } | 3875 | } |
3688 | if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL))) && | 3876 | if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL))) && |
3689 | (1 == use_pipe) && | 3877 | (1 == use_pipe) && |
3690 | (!MHD_SCKT_FD_FITS_FDSET_(daemon->wpipe[0], NULL)) ) | 3878 | (! MHD_SCKT_FD_FITS_FDSET_(daemon->wpipe[0], NULL)) ) |
3691 | { | 3879 | { |
3692 | #ifdef HAVE_MESSAGES | 3880 | #ifdef HAVE_MESSAGES |
3693 | MHD_DLOG (daemon, | 3881 | MHD_DLOG (daemon, |