ASF Bugzilla – Attachment 34685 Details for
Bug 56188
mod_proxy_fcgi does not send FCGI_ABORT_REQUEST on client disconnect
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
httpd-trunk-mod_proxy_fcgi-client_disconnected.patch
httpd-trunk-mod_proxy_fcgi-client_disconnected.patch (text/plain), 7.36 KB, created by
Luca Toscano
on 2017-01-27 18:44:44 UTC
(
hide
)
Description:
httpd-trunk-mod_proxy_fcgi-client_disconnected.patch
Filename:
MIME Type:
Creator:
Luca Toscano
Created:
2017-01-27 18:44:44 UTC
Size:
7.36 KB
patch
obsolete
>Index: modules/proxy/mod_proxy_fcgi.c >=================================================================== >--- modules/proxy/mod_proxy_fcgi.c (revision 1780356) >+++ modules/proxy/mod_proxy_fcgi.c (working copy) >@@ -40,6 +40,10 @@ > fcgi_backend_t backend_type; > } fcgi_dirconf_t; > >+typedef struct { >+ int detect_client_disconnect; >+} fcgi_serverconf_t; >+ > /* > * Canonicalise http-like URLs. > * scheme is the scheme for the URL >@@ -497,7 +501,7 @@ > apr_uint16_t request_id, const char **err, > int *bad_request, int *has_responded) > { >- apr_bucket_brigade *ib, *ob; >+ apr_bucket_brigade *ib, *ob, *cib; > int seen_end_of_headers = 0, done = 0, ignore_body = 0; > apr_status_t rv = APR_SUCCESS; > int script_error_status = HTTP_OK; >@@ -505,7 +509,7 @@ > struct iovec vec[2]; > ap_fcgi_header header; > unsigned char farray[AP_FCGI_HEADER_LEN]; >- apr_pollfd_t pfd; >+ apr_pollfd_t pfd[2]; > int header_state = HDR_STATE_READING_HEADERS; > char stack_iobuf[AP_IOBUFSIZE]; > apr_size_t iobuf_size = AP_IOBUFSIZE; >@@ -517,14 +521,25 @@ > iobuf = apr_palloc(r->pool, iobuf_size); > } > >- pfd.desc_type = APR_POLL_SOCKET; >- pfd.desc.s = conn->sock; >- pfd.p = r->pool; >- pfd.reqevents = APR_POLLIN | APR_POLLOUT; >+ pfd[0].desc_type = APR_POLL_SOCKET; >+ pfd[0].desc.s = conn->sock; >+ pfd[0].p = r->pool; >+ pfd[0].reqevents = APR_POLLIN | APR_POLLOUT; > >+ /* Specific pollfd to detect client connection aborts */ >+ pfd[1].desc_type = APR_POLL_SOCKET; >+ pfd[1].desc.s = (apr_socket_t*) ap_get_module_config(r->connection->conn_config, >+ &core_module); >+ pfd[1].p = r->connection->pool; >+ pfd[1].reqevents = APR_POLLIN; >+ > ib = apr_brigade_create(r->pool, c->bucket_alloc); > ob = apr_brigade_create(r->pool, c->bucket_alloc); >+ cib = apr_brigade_create(r->connection->pool, c->bucket_alloc); > >+ fcgi_serverconf_t *cfg = ap_get_module_config(r->server->module_config, >+ &proxy_fcgi_module); >+ > while (! done) { > apr_interval_time_t timeout; > apr_size_t len; >@@ -534,7 +549,7 @@ > * cause timeout errors. */ > apr_socket_timeout_get(conn->sock, &timeout); > >- rv = apr_poll(&pfd, 1, &n, timeout); >+ rv = apr_poll(pfd, 2, &n, timeout); > if (rv != APR_SUCCESS) { > if (APR_STATUS_IS_EINTR(rv)) { > continue; >@@ -543,7 +558,7 @@ > break; > } > >- if (pfd.rtnevents & APR_POLLOUT) { >+ if (pfd[0].rtnevents & APR_POLLOUT) { > apr_size_t to_send, writebuflen; > int last_stdin = 0; > char *iobuf_cursor; >@@ -608,7 +623,7 @@ > } > > if (last_stdin) { >- pfd.reqevents = APR_POLLIN; /* Done with input data */ >+ pfd[0].reqevents = APR_POLLIN; /* Done with input data */ > > /* signal EOF (empty FCGI_STDIN) */ > ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id, >@@ -626,7 +641,36 @@ > } > } > >- if (pfd.rtnevents & APR_POLLIN) { >+ /* >+ * Client connection aborted before any attempt to flush >+ * data out has been made. This can happen for long running FCGI >+ * tasks. According to the FCGI specs, an FCGI_ABORT should be sent >+ * and the FCGI backend should respond with an FCGI_END_REQUEST, but as of >+ * today (December 2016) there seems to be no FCGI backend implementation >+ * that really honor/care about this functionality. Since this module >+ * does not implement FCGI request multiplexing, it seems more consistent >+ * to follow this bit of the FCGI_ABORT spec: >+ * "When a Web server is not multiplexing requests over a transport >+ * connection, the Web server can abort a request by closing >+ * the request's transport connection." >+ */ >+ if (pfd[1].rtnevents & APR_POLLIN) { >+ if (cfg->detect_client_disconnect) { >+ rv = ap_get_brigade(r->connection->input_filters, cib, >+ AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 8); >+ if(rv == APR_EOF) { >+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, >+ "EOF detected from the main client connection."); >+ r->connection->aborted = 1; >+ break; >+ } >+ } else { >+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, >+ "Client disconnect detector disabled!"); >+ } >+ } >+ >+ if (pfd[0].rtnevents & APR_POLLIN) { > apr_size_t readbuflen; > apr_uint16_t clen, rid; > apr_bucket *b; >@@ -855,6 +899,7 @@ > > apr_brigade_destroy(ib); > apr_brigade_destroy(ob); >+ apr_brigade_destroy(cib); > > if (script_error_status != HTTP_OK) { > ap_die(script_error_status, r); /* send ErrorDocument */ >@@ -1052,6 +1097,25 @@ > return a; > } > >+static void *fcgi_create_sconf(apr_pool_t *p, server_rec *s) >+{ >+ fcgi_serverconf_t *a; >+ >+ a = (fcgi_serverconf_t *) apr_pcalloc(p, sizeof(fcgi_serverconf_t)); >+ a->detect_client_disconnect = 0; >+ return a; >+} >+ >+static void *fcgi_merge_sconf(apr_pool_t *p, void *basev, void *overridesv) >+{ >+ fcgi_serverconf_t *a, *override; >+ >+ override = (fcgi_serverconf_t *) overridesv; >+ a = (fcgi_serverconf_t *) apr_pcalloc(p, sizeof(fcgi_serverconf_t)); >+ a->detect_client_disconnect = override->detect_client_disconnect; >+ return a; >+} >+ > static const char *cmd_servertype(cmd_parms *cmd, void *in_dconf, > const char *val) > { >@@ -1071,6 +1135,18 @@ > return NULL; > } > >+const char *cmd_client_disconnect(cmd_parms *cmd, void *cfg, const char *arg) >+{ >+ fcgi_serverconf_t *config = ap_get_module_config(cmd->server->module_config, >+ &proxy_fcgi_module); >+ if(!strcasecmp(arg, "on")) { >+ config->detect_client_disconnect = 1; >+ } else { >+ config->detect_client_disconnect = 0; >+ } >+ return NULL; >+} >+ > static void register_hooks(apr_pool_t *p) > { > proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST); >@@ -1080,6 +1156,9 @@ > static const command_rec command_table[] = { > AP_INIT_TAKE1("ProxyFCGIBackendType", cmd_servertype, NULL, OR_FILEINFO, > "Specify the type of FastCGI server: 'Generic', 'FPM'"), >+ AP_INIT_TAKE1("ProxyFCGIDetectClientDisconnect", cmd_client_disconnect, >+ NULL, RSRC_CONF, "Detect when a client connection is dropped" >+ " and close the connection with the FCGI backend."), > { NULL } > }; > >@@ -1087,8 +1166,8 @@ > STANDARD20_MODULE_STUFF, > fcgi_create_dconf, /* create per-directory config structure */ > fcgi_merge_dconf, /* merge per-directory config structures */ >- NULL, /* create per-server config structure */ >- NULL, /* merge per-server config structures */ >+ fcgi_create_sconf, /* create per-server config structure */ >+ fcgi_merge_sconf, /* merge per-server config structures */ > command_table, /* command apr_table_t */ > register_hooks /* register hooks */ > };
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 56188
:
33336
|
33433
|
34073
|
34560
|
34572
|
34574
|
34685
|
34692