From ddfae019cb5ec54636607ac45ac56c7e27a0f16b Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Fri, 10 Jun 2016 23:34:55 -0400 Subject: [PATCH] separate routines for reading output from backends move code in dynamic handlers (CGI, FastCGI, SCGI, proxy) from *_handle_fdevent() to *_recv_response() for reuse outside the *_handle_fdevent() routine --- src/mod_cgi.c | 22 +++++++++++------ src/mod_fastcgi.c | 25 ++++++++++++++++---- src/mod_proxy.c | 60 ++++++++++++++++++++++++++++++----------------- src/mod_scgi.c | 39 +++++++++++++++++++++--------- 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/src/mod_cgi.c b/src/mod_cgi.c index 8f630fa5..1764dd61 100644 --- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -719,13 +719,7 @@ static handler_t cgi_handle_fdevent_send (server *srv, void *ctx, int revents) { } -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) { +static int cgi_recv_response(server *srv, handler_ctx *hctx) { switch (cgi_demux_response(srv, hctx)) { case FDEVENT_HANDLED_NOT_FINISHED: break; @@ -745,6 +739,20 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) { cgi_connection_close(srv, hctx); return HANDLER_FINISHED; } + + return HANDLER_GO_ON; +} + + +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 */ diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index 874e357b..5d53ac63 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -3164,6 +3164,9 @@ static handler_t fcgi_send_request(server *srv, handler_ctx *hctx) { } +static handler_t fcgi_recv_response(server *srv, handler_ctx *hctx); + + SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) { plugin_data *p = p_d; @@ -3201,17 +3204,14 @@ SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) { : HANDLER_WAIT_FOR_EVENT; } -static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) { - handler_ctx *hctx = ctx; + +static handler_t fcgi_recv_response(server *srv, handler_ctx *hctx) { connection *con = hctx->remote_conn; plugin_data *p = hctx->plugin_data; fcgi_proc *proc = hctx->proc; fcgi_extension_host *host= hctx->host; - joblist_append(srv, con); - - if (revents & FDEVENT_IN) { switch (fcgi_demux_response(srv, hctx)) { case 0: break; @@ -3326,6 +3326,20 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) { return HANDLER_FINISHED; } + + return HANDLER_GO_ON; +} + + +static handler_t fcgi_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 = fcgi_recv_response(srv, hctx);/*(might invalidate hctx)*/ + if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/ } if (revents & FDEVENT_OUT) { @@ -3354,6 +3368,7 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) { * even if the FCGI_FIN packet is not received yet */ } else { + fcgi_proc *proc = hctx->proc; log_error_write(srv, __FILE__, __LINE__, "sBSbsbsd", "error: unexpected close of fastcgi connection for", con->uri.path, "?", con->uri.query, diff --git a/src/mod_proxy.c b/src/mod_proxy.c index 08465b8e..9a4982ec 100644 --- a/src/mod_proxy.c +++ b/src/mod_proxy.c @@ -911,6 +911,10 @@ static handler_t proxy_send_request(server *srv, handler_ctx *hctx) { } } + +static handler_t proxy_recv_response(server *srv, handler_ctx *hctx); + + SUBREQUEST_FUNC(mod_proxy_handle_subrequest) { plugin_data *p = p_d; @@ -948,6 +952,38 @@ SUBREQUEST_FUNC(mod_proxy_handle_subrequest) { : HANDLER_WAIT_FOR_EVENT; } + +static handler_t proxy_recv_response(server *srv, handler_ctx *hctx) { + + switch (proxy_demux_response(srv, hctx)) { + case 0: + break; + case 1: + /* we are done */ + proxy_connection_close(srv, hctx); + + return HANDLER_FINISHED; + case -1: { + connection *con = hctx->remote_conn; + if (con->file_started == 0) { + /* reading response headers failed */ + } else { + /* response might have been already started, kill the connection */ + con->keep_alive = 0; + con->file_finished = 1; + con->mode = DIRECT; /*(avoid sending final chunked block)*/ + } + + proxy_connection_close(srv, hctx); + + return HANDLER_FINISHED; + } + } + + return HANDLER_GO_ON; +} + + static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) { handler_ctx *hctx = ctx; connection *con = hctx->remote_conn; @@ -962,27 +998,9 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) { "proxy: fdevent-in", hctx->state); } - switch (proxy_demux_response(srv, hctx)) { - case 0: - break; - case 1: - /* we are done */ - proxy_connection_close(srv, hctx); - - return HANDLER_FINISHED; - case -1: - if (con->file_started == 0) { - /* reading response headers failed */ - } else { - /* response might have been already started, kill the connection */ - con->keep_alive = 0; - con->file_finished = 1; - con->mode = DIRECT; /*(avoid sending final chunked block)*/ - } - - proxy_connection_close(srv, hctx); - - return HANDLER_FINISHED; + { + handler_t rc = proxy_recv_response(srv,hctx);/*(might invalidate hctx)*/ + if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/ } } diff --git a/src/mod_scgi.c b/src/mod_scgi.c index 5bd8714d..0c674224 100644 --- a/src/mod_scgi.c +++ b/src/mod_scgi.c @@ -2519,6 +2519,10 @@ static handler_t scgi_send_request(server *srv, handler_ctx *hctx) { } } + +static handler_t scgi_recv_response(server *srv, handler_ctx *hctx); + + SUBREQUEST_FUNC(mod_scgi_handle_subrequest) { plugin_data *p = p_d; @@ -2557,17 +2561,8 @@ SUBREQUEST_FUNC(mod_scgi_handle_subrequest) { } -static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) { - handler_ctx *hctx = ctx; - connection *con = hctx->remote_conn; - plugin_data *p = hctx->plugin_data; +static handler_t scgi_recv_response(server *srv, handler_ctx *hctx) { - scgi_proc *proc = hctx->proc; - scgi_extension_host *host= hctx->host; - - joblist_append(srv, con); - - if (revents & FDEVENT_IN) { switch (scgi_demux_response(srv, hctx)) { case 0: break; @@ -2576,7 +2571,13 @@ static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) { scgi_connection_close(srv, hctx); return HANDLER_FINISHED; - case -1: + case -1: { + connection *con = hctx->remote_conn; + plugin_data *p = hctx->plugin_data; + + scgi_proc *proc = hctx->proc; + scgi_extension_host *host= hctx->host; + if (proc->pid && proc->state != PROC_STATE_DIED) { int status; @@ -2660,6 +2661,21 @@ static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) { return HANDLER_FINISHED; } + } + + return HANDLER_GO_ON; +} + + +static handler_t scgi_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 = scgi_recv_response(srv, hctx);/*(might invalidate hctx)*/ + if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/ } if (revents & FDEVENT_OUT) { @@ -2680,6 +2696,7 @@ static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) { */ scgi_send_request(srv, hctx); } else { + scgi_extension_host *host= hctx->host; log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", "error: unexpected close of scgi connection for", con->uri.path,