From 7a1f16b5125c57b1619bb6dfa8c1239ddc603c80 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Sat, 3 Mar 2018 12:18:37 +0000 Subject: [PATCH] Merge r1802040, r1807876, r1808014, r1805490, r1823886 from trunk: MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit mod_proxy_fcgi: Add the support for mod_proxy's flushpackets and flushwait params This change was requested on the development mailing list in order to fill another gap between mod_fcgi and mod_proxy_fcgi, namely the -flush funtionality. The more evolved core trunk code would not need this feature becuse of the non-blocking writes, but it is be needed in 2.4.x. mod_proxy_fcgi: limit the flush buckets inserted when flushpackets=on|auto This commit is a follow up of r1802040 based on Jacob's feedback, namely inserting the FLUSH buckets only when really needed and useful, not always. mod_proxy_fcgi: follow up to r1807876. Fix mixed declarations and code [-Wdeclaration-after-statement]. Fix a compilation warning introduced by r1802040. mod_proxy_fcgi.c:893:19: warning: ‘flushpoll’ may be used uninitialized in this function [-Wmaybe-uninitialized] This warning is a false positive. mod_proxy_fcgi: prioritize the check for mayflush when using flushpackets The mayflush variable should be checked before the rest to avoid polling when not needed. Suggested by Yann Ylavic on the dev@ mailing list. Submitted by: elukey, ylavic, jailletc36, elukey Reviewed by: elukey, jim, ylavic git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1825765 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ docs/manual/mod/mod_proxy.xml | 2 +- modules/proxy/mod_proxy_fcgi.c | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 3ab0b27376..99887ea3fd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.31 + *) mod_proxy_fcgi: Add the support for mod_proxy's flushpackets and flushwait + parameters. [Luca Toscano, Ruediger Pluem, Yann Ylavic] + *) mod_ldap: Avoid possible crashes, hangs, and busy loops due to improper merging of the cache lock in vhost config. PR 43164 [Eric Covener] diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index 4bd5146986..44a5f66bf2 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -1082,7 +1082,7 @@ ProxyPass "/mirror/foo" "http://backend.example.com" only when needed; 'on' means after each chunk is sent; and 'auto' means poll/wait for a period of time and flush if no input has been received for 'flushwait' milliseconds. - Currently, this is in effect only for AJP. + Currently, this is in effect only for mod_proxy_ajp and mod_proxy_fcgi. flushwait 10 diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index 41292e8726..2e97408f3f 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -532,6 +532,8 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, ap_fcgi_header header; unsigned char farray[AP_FCGI_HEADER_LEN]; apr_pollfd_t pfd; + apr_pollfd_t *flushpoll = NULL; + apr_int32_t flushpoll_fd; int header_state = HDR_STATE_READING_HEADERS; char stack_iobuf[AP_IOBUFSIZE]; apr_size_t iobuf_size = AP_IOBUFSIZE; @@ -548,6 +550,13 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, pfd.p = r->pool; pfd.reqevents = APR_POLLIN | APR_POLLOUT; + if (conn->worker->s->flush_packets == flush_auto) { + flushpoll = apr_pcalloc(r->pool, sizeof(apr_pollfd_t)); + flushpoll->reqevents = APR_POLLIN; + flushpoll->desc_type = APR_POLL_SOCKET; + flushpoll->desc.s = conn->sock; + } + ib = apr_brigade_create(r->pool, c->bucket_alloc); ob = apr_brigade_create(r->pool, c->bucket_alloc); @@ -658,6 +667,7 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, apr_bucket *b; unsigned char plen; unsigned char type, version; + int mayflush = 0; /* First, we grab the header... */ rv = get_data_full(conn, (char *) farray, AP_FCGI_HEADER_LEN); @@ -786,6 +796,7 @@ recv_again: *err = "passing brigade to output filters"; break; } + mayflush = 1; } apr_brigade_cleanup(ob); @@ -812,6 +823,7 @@ recv_again: *err = "passing brigade to output filters"; break; } + mayflush = 1; } apr_brigade_cleanup(ob); } @@ -876,6 +888,20 @@ recv_again: break; } } + + if (mayflush && ((conn->worker->s->flush_packets == flush_on) || + ((conn->worker->s->flush_packets == flush_auto) && + (apr_poll(flushpoll, 1, &flushpoll_fd, + conn->worker->s->flush_wait) == APR_TIMEUP)))) { + apr_bucket* flush_b = apr_bucket_flush_create(r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ob, flush_b); + rv = ap_pass_brigade(r->output_filters, ob); + if (rv != APR_SUCCESS) { + *err = "passing headers brigade to output filters"; + break; + } + mayflush = 0; + } } } -- 2.40.0