libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit e3aee92d569469c2b7103c1ce1564c01ebd08b3a
parent 599561d60c0c5769b4cebb525d81aa4efa9688f4
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 17 Oct 2016 13:50:27 +0200

get test_upgrade_ssl to pass again

Diffstat:
Msrc/microhttpd/connection_https.c | 2+-
Msrc/microhttpd/daemon.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/microhttpd/internal.h | 8++++----
Msrc/microhttpd/response.c | 43+++++++++++++++++++++++--------------------
Msrc/microhttpd/test_upgrade_ssl.c | 1-
5 files changed, 78 insertions(+), 52 deletions(-)

diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c @@ -48,7 +48,7 @@ run_tls_handshake (struct MHD_Connection *connection) { int ret; - connection->last_activity = MHD_monotonic_sec_counter(); + connection->last_activity = MHD_monotonic_sec_counter (); if (MHD_TLS_CONNECTION_INIT == connection->state) { ret = gnutls_handshake (connection->tls_session); diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -764,6 +764,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, unsigned int fd_setsize) { struct MHD_Connection *pos; + struct MHD_Connection *posn; int result = MHD_YES; if ( (NULL == daemon) || @@ -792,8 +793,10 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, fd_setsize)) ) result = MHD_NO; - for (pos = daemon->connections_head; NULL != pos; pos = pos->next) + for (pos = daemon->connections_head; NULL != pos; pos = posn) { + posn = pos->next; + switch (pos->event_loop_info) { case MHD_EVENT_LOOP_INFO_READ: @@ -971,9 +974,23 @@ MHD_cleanup_upgraded_connection_ (struct MHD_Connection *connection) } #endif /* HTTPS_SUPPORT */ if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) - MHD_resume_connection (connection); - MHD_connection_close_ (connection, - MHD_REQUEST_TERMINATED_COMPLETED_OK); + { + /* resuming the connection will indirectly close it */ + MHD_resume_connection (connection); +#if HTTPS_SUPPORT + if (0 != (daemon->options & MHD_USE_TLS)) + { + gnutls_bye (connection->tls_session, + GNUTLS_SHUT_RDWR); + } +#endif + } + else + { + /* the thread would no longer close it */ + MHD_connection_close_ (connection, + MHD_REQUEST_TERMINATED_COMPLETED_OK); + } connection->urh = NULL; if (NULL != urh) @@ -987,10 +1004,8 @@ MHD_cleanup_upgraded_connection_ (struct MHD_Connection *connection) * based on the readyness state stored in the @a urh handle. * * @param urh handle to process - * @return #MHD_YES if we are done reading from the socket, - * #MHD_NO if there might be more data to be read */ -static int +static void process_urh (struct MHD_UpgradeResponseHandle *urh) { int fin_read; @@ -1122,7 +1137,13 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) urh->out_buffer_off = 0; } } - return fin_read; + /* cleanup connection if it was closed and all data was sent */ + if ( (MHD_YES == urh->was_closed) && + (0 == urh->out_buffer_off) && + (MHD_YES == fin_read) ) + { + MHD_cleanup_upgraded_connection_ (urh->connection); + } } #endif @@ -2520,13 +2541,9 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && - (MHD_NO == pos->thread_joined) ) - { - if (! MHD_join_thread_ (pos->pid)) - { - MHD_PANIC (_("Failed to join a thread\n")); - } - } + (MHD_NO == pos->thread_joined) && + (! MHD_join_thread_ (pos->pid)) ) + MHD_PANIC (_("Failed to join a thread\n")); MHD_pool_destroy (pos->pool); #if HTTPS_SUPPORT if (NULL != pos->tls_session) @@ -2578,9 +2595,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) pos->response = NULL; } if (MHD_INVALID_SOCKET != pos->socket_fd) - { - MHD_socket_close_chk_ (pos->socket_fd); - } + MHD_socket_close_chk_ (pos->socket_fd); if (NULL != pos->addr) free (pos->addr); free (pos); @@ -2776,20 +2791,13 @@ MHD_run_from_select (struct MHD_Daemon *daemon, #if HTTPS_SUPPORT for (urh = daemon->urh_head; NULL != urh; urh = urhn) { - int fin_read; - urhn = urh->next; /* update urh state based on select() output */ urh_from_fdset (urh, read_fd_set, write_fd_set); /* call generic forwarding function for passing data */ - fin_read = process_urh (urh); - /* cleanup connection if it was closed and all data was sent */ - if ( (MHD_YES == urh->was_closed) && - (0 == urh->out_buffer_off) && - (MHD_YES == fin_read) ) - MHD_cleanup_upgraded_connection_ (urh->connection); + process_urh (urh); } #endif MHD_cleanup_connections (daemon); @@ -5262,10 +5270,26 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) { MHD_socket fd; unsigned int i; +#if HTTPS_SUPPORT + struct MHD_UpgradeResponseHandle *urh; + struct MHD_UpgradeResponseHandle *urhn; +#endif if (NULL == daemon) return; + /* give upgraded HTTPS connections a chance to finish */ +#if HTTPS_SUPPORT + for (urh = daemon->urh_head; NULL != urh; urh = urhn) + { + urhn = urh->next; + /* call generic forwarding function for passing data + with chance to detect that application is done; + fake read readyness just to be sure. */ + urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; + process_urh (urh); + } +#endif if (0 != (MHD_USE_SUSPEND_RESUME & daemon->options)) resume_suspended_connections (daemon); daemon->shutdown = MHD_YES; diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -882,10 +882,10 @@ struct MHD_Connection /** * If this connection was upgraded and if we are using - * #MHD_USE_THREAD_PER_CONNECTION, this points to the - * upgrade response details such that the - * #thread_main_connection_upgrade()-logic can perform - * the bi-directional forwarding. + * #MHD_USE_THREAD_PER_CONNECTION or #MHD_USE_TLS, this points to + * the upgrade response details such that the + * #thread_main_connection_upgrade()-logic can perform the + * bi-directional forwarding. */ struct MHD_UpgradeResponseHandle *urh; diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c @@ -634,17 +634,17 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, case MHD_UPGRADE_ACTION_CLOSE: /* transition to special 'closed' state for start of cleanup */ connection->state = MHD_CONNECTION_UPGRADE_CLOSED; +#if HTTPS_SUPPORT + if (0 != (daemon->options & MHD_USE_TLS) ) + { + /* signal that app is done by shutdown() of 'app' socket */ + shutdown (urh->app.socket, + SHUT_RDWR); + } +#endif /* Application is done with this connection, tear it down! */ if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) { -#if HTTPS_SUPPORT - if (0 != (daemon->options & MHD_USE_TLS) ) - { - /* signal thread that app is done by shutdown() of 'app' socket */ - shutdown (urh->app.socket, - SHUT_RDWR); - } -#endif /* need to signal the thread that we are done */ MHD_semaphore_up (connection->upgrade_sem); /* connection and urh cleanup will be done in connection's thread */ @@ -670,9 +670,9 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, /** - * We are done sending the header of a given response - * to the client. Now it is time to perform the upgrade - * and hand over the connection to the application. + * We are done sending the header of a given response to the client. + * Now it is time to perform the upgrade and hand over the connection + * to the application. * * @param response the response that was created for an upgrade * @param connection the specific connection we are upgrading @@ -717,16 +717,16 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, #ifdef MHD_socket_pair_nblk_ if (! MHD_socket_pair_nblk_ (sv)) - { - free (urh); - return MHD_NO; - } + { + free (urh); + return MHD_NO; + } #else /* !MHD_socket_pair_nblk_ */ if (! MHD_socket_pair_ (sv)) - { - free (urh); - return MHD_NO; - } + { + free (urh); + return MHD_NO; + } if ( (! MHD_socket_nonblocking_(sv[0])) || (! MHD_socket_nonblocking_(sv[1])) ) { @@ -737,7 +737,8 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, #endif } #endif /* !MHD_socket_pair_nblk_ */ - if ( (! MHD_SCKT_FD_FITS_FDSET_(sv[1], NULL)) && + if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1], + NULL)) && (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) { #ifdef HAVE_MESSAGES @@ -862,6 +863,8 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, DLL_insert (daemon->urh_head, daemon->urh_tail, urh); + /* Keep reference for later removal from the DLL */ + connection->urh = urh; } else { diff --git a/src/microhttpd/test_upgrade_ssl.c b/src/microhttpd/test_upgrade_ssl.c @@ -193,7 +193,6 @@ main (int argc, MHD_USE_TLS_EPOLL_UPGRADE, 2); #endif - /* report result */ if (0 != error_count) fprintf (stderr,