static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) { handler_ctx *hctx = ctx; connection *con = hctx->remote_conn; joblist_append(srv, con); if (revents & FDEVENT_IN) { handler_t rc = cgi_recv_response(srv, hctx);/*(might invalidate hctx)*/ if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/ } /* perhaps this issue is already handled */ if (revents & FDEVENT_HUP) { if (con->file_started) { /* drain any remaining data from kernel pipe buffers * even if (con->conf.stream_response_body * & FDEVENT_STREAM_RESPONSE_BUFMIN) * since event loop will spin on fd FDEVENT_HUP event * until unregistered. */ handler_t rc; do { rc = cgi_recv_response(srv,hctx);/*(might invalidate hctx)*/ } while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/ return rc; /* HANDLER_FINISHED or HANDLER_COMEBACK or HANDLER_ERROR */ } else if (!buffer_string_is_empty(hctx->response_header)) { /* unfinished header package which is a body in reality */ con->file_started = 1; if (0 != http_chunk_append_buffer(srv, con, hctx->response_header)) { cgi_connection_close(srv, hctx); return HANDLER_ERROR; } } else { # if 0 log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents); # endif } cgi_connection_close(srv, hctx); } else if (revents & FDEVENT_ERR) { /* kill all connections to the cgi process */ cgi_connection_close(srv, hctx); #if 1 log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR"); #endif return HANDLER_ERROR; } return HANDLER_FINISHED; }
static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) { handler_ctx *hctx = ctx; connection *con = hctx->remote_conn; joblist_append(srv, con); if (revents & FDEVENT_IN) { handler_t rc = cgi_recv_response(srv, hctx);/*(might invalidate hctx)*/ if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/ } /* perhaps this issue is already handled */ if (revents & (FDEVENT_HUP|FDEVENT_RDHUP)) { if (con->file_started) { /* drain any remaining data from kernel pipe buffers * even if (con->conf.stream_response_body * & FDEVENT_STREAM_RESPONSE_BUFMIN) * since event loop will spin on fd FDEVENT_HUP event * until unregistered. */ handler_t rc; const unsigned short flags = con->conf.stream_response_body; con->conf.stream_response_body &= ~FDEVENT_STREAM_RESPONSE_BUFMIN; con->conf.stream_response_body |= FDEVENT_STREAM_RESPONSE_POLLRDHUP; do { rc = cgi_recv_response(srv,hctx);/*(might invalidate hctx)*/ } while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/ con->conf.stream_response_body = flags; return rc; /* HANDLER_FINISHED or HANDLER_COMEBACK or HANDLER_ERROR */ } else if (!buffer_string_is_empty(hctx->response)) { /* unfinished header package which is a body in reality */ con->file_started = 1; if (0 != http_chunk_append_buffer(srv, con, hctx->response)) { cgi_connection_close(srv, hctx); return HANDLER_ERROR; } if (0 == con->http_status) con->http_status = 200; /* OK */ } cgi_connection_close(srv, hctx); } else if (revents & FDEVENT_ERR) { /* kill all connections to the cgi process */ cgi_connection_close(srv, hctx); return HANDLER_ERROR; } return HANDLER_FINISHED; }