diff --git a/CHANGES b/CHANGES
index ceca74b249..86c250e53c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) mod_proxy_fcgi: Add the support for mod_proxy's flushpackets and flushwait
+ parameters. [Luca Toscano, Ruediger Pluem, Yann Ylavic]
+
*) mod_proxy_wstunnel: Fix detection of unresponded request which could have
led to spurious HTTP 502 error messages sent on upgrade connections.
PR 61283. [Yann Ylavic]
diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml
index 746436f18c..a97abc36d9 100644
--- a/docs/manual/mod/mod_proxy.xml
+++ b/docs/manual/mod/mod_proxy.xml
@@ -1089,7 +1089,7 @@ ProxyPass "/example" "http://backend.example.com" max=20 ttl=120 retry=300
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..019f4a9335 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;
+ 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);
@@ -876,6 +885,19 @@ recv_again:
break;
}
}
+
+ if ((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;
+ }
+ }
}
}