/** * This function was created to handle per-connection processing that * has to happen even if the socket cannot be read or written to. All * implementations (multithreaded, external select, internal select) * call this function. * * @param connection being handled * @return MHD_YES if we should continue to process the * connection (not dead yet), MHD_NO if it died */ static int MHD_tls_connection_handle_idle (struct MHD_Connection *connection) { unsigned int timeout; #if DEBUG_STATES MHD_DLOG (connection->daemon, "%s: state: %s\n", __FUNCTION__, MHD_state_to_string (connection->state)); #endif timeout = connection->daemon->connection_timeout; if ((connection->socket_fd != -1) && (timeout != 0) && (time (NULL) - timeout > connection->last_activity)) { MHD_tls_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); return MHD_NO; } switch (connection->state) { /* on newly created connections we might reach here before any reply has been received */ case MHD_TLS_CONNECTION_INIT: return MHD_YES; /* close connection if necessary */ case MHD_CONNECTION_CLOSED: if (connection->socket_fd != -1) MHD_tls_connection_close (connection, MHD_REQUEST_TERMINATED_COMPLETED_OK); return MHD_NO; default: return MHD_connection_handle_idle (connection); } return MHD_YES; }
/** * This function was created to handle per-connection processing that * has to happen even if the socket cannot be read or written to. All * implementations (multithreaded, external select, internal select) * call this function. * * @param connection being handled * @return MHD_YES if we should continue to process the * connection (not dead yet), MHD_NO if it died */ static int MHD_tls_connection_handle_idle (struct MHD_Connection *connection) { unsigned int timeout; #if DEBUG_STATES MHD_DLOG (connection->daemon, "%s: state: %s\n", __FUNCTION__, MHD_state_to_string (connection->state)); #endif timeout = connection->connection_timeout; if ( (timeout != 0) && (time (NULL) - timeout > connection->last_activity)) MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); switch (connection->state) { /* on newly created connections we might reach here before any reply has been received */ case MHD_TLS_CONNECTION_INIT: return MHD_YES; /* close connection if necessary */ case MHD_CONNECTION_CLOSED: gnutls_bye (connection->tls_session, GNUTLS_SHUT_RDWR); return MHD_connection_handle_idle (connection); default: if ( (0 != gnutls_record_check_pending (connection->tls_session)) && (MHD_YES != MHD_tls_connection_handle_read (connection)) ) return MHD_YES; return MHD_connection_handle_idle (connection); } return MHD_YES; }
/** * This function was created to handle writes to sockets when it has * been determined that the socket can be written to. This function * will forward all write requests to the underlying daemon unless * the connection has been marked for closing. * * @return MHD_connection_handle_write() if we should continue to * process the connection (not dead yet), MHD_NO if it died */ static int MHD_tls_connection_handle_write (struct MHD_Connection *connection) { int ret; connection->last_activity = time (NULL); #if DEBUG_STATES MHD_DLOG (connection->daemon, "%s: state: %s\n", __FUNCTION__, MHD_state_to_string (connection->state)); #endif if (connection->state == MHD_TLS_CONNECTION_INIT) { ret = gnutls_handshake (connection->tls_session); if (ret == GNUTLS_E_SUCCESS) { /* set connection state to enable HTTP processing */ connection->state = MHD_CONNECTION_INIT; return MHD_YES; } if ( (ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED) ) { /* handshake not done */ return MHD_YES; } /* handshake failed */ #if HAVE_MESSAGES MHD_DLOG (connection->daemon, "Error: received handshake message out of context\n"); #endif MHD_tls_connection_close (connection, MHD_REQUEST_TERMINATED_WITH_ERROR); return MHD_NO; } return MHD_connection_handle_write (connection); }
/** * This function was created to handle per-connection processing that * has to happen even if the socket cannot be read or written to. All * implementations (multithreaded, external select, internal select) * call this function. * * @param connection being handled * @return #MHD_YES if we should continue to process the * connection (not dead yet), #MHD_NO if it died */ static int MHD_tls_connection_handle_idle (struct MHD_Connection *connection) { unsigned int timeout; #if DEBUG_STATES MHD_DLOG (connection->daemon, _("In function %s handling connection at state: %s\n"), __FUNCTION__, MHD_state_to_string (connection->state)); #endif timeout = connection->connection_timeout; if ( (timeout != 0) && (timeout <= (MHD_monotonic_sec_counter() - connection->last_activity))) MHD_connection_close_ (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); switch (connection->state) { /* on newly created connections we might reach here before any reply has been received */ case MHD_TLS_CONNECTION_INIT: break; /* close connection if necessary */ case MHD_CONNECTION_CLOSED: return MHD_connection_handle_idle (connection); default: if ( (0 != gnutls_record_check_pending (connection->tls_session)) && (MHD_YES != MHD_tls_connection_handle_read (connection)) ) return MHD_YES; return MHD_connection_handle_idle (connection); } #ifdef EPOLL_SUPPORT return MHD_connection_epoll_update_ (connection); #else return MHD_YES; #endif }