* modules/fcgid/fcgid_proc_unix.c (proc_write_ipc): Use constant
memory for large requests.
* modules/fcgid/fcgid_proc_win.c (proc_write_ipc): Likewise.
PR: 51747
Submitted by: Dominic Benson <dominic.benson thirdlight.com>,
Jan Stürtz <js contact.de>
git-svn-id: https://svn.apache.org/repos/asf/httpd/mod_fcgid/trunk@1847624 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES-FCGID b/CHANGES-FCGID
index 17d4a70..541662a 100644
--- a/CHANGES-FCGID
+++ b/CHANGES-FCGID
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with mod_fcgid 2.3.10
+ *) Fix memory consumption for large requests. PR 51747.
+ [Dominic Benson, Jan Stürtz]
+
*) Use an alternate, lower severity log message when a failure to
forward a response is due to the client connection being aborted.
[Eric Covener]
diff --git a/modules/fcgid/fcgid_proc_unix.c b/modules/fcgid/fcgid_proc_unix.c
index 218f3f7..7f37495 100644
--- a/modules/fcgid/fcgid_proc_unix.c
+++ b/modules/fcgid/fcgid_proc_unix.c
@@ -762,14 +762,18 @@
struct iovec vec[FCGID_VEC_COUNT];
int nvec = 0;
apr_bucket *e;
+ apr_bucket_brigade *tmpbb = apr_brigade_create(output_brigade->p,
+ output_brigade->bucket_alloc);
- for (e = APR_BRIGADE_FIRST(output_brigade);
- e != APR_BRIGADE_SENTINEL(output_brigade);
- e = APR_BUCKET_NEXT(e)) {
+ while (!APR_BRIGADE_EMPTY(output_brigade))
+ {
+ e = APR_BRIGADE_FIRST(output_brigade);
+
apr_size_t len;
const char* base;
if (APR_BUCKET_IS_METADATA(e)) {
+ apr_bucket_delete(e);
continue;
}
@@ -780,6 +784,9 @@
return rv;
}
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(tmpbb, e);
+
vec[nvec].iov_len = len;
vec[nvec].iov_base = (char*) base;
if (nvec == (FCGID_VEC_COUNT - 1)) {
@@ -789,6 +796,7 @@
FCGID_VEC_COUNT)) != APR_SUCCESS)
return rv;
nvec = 0;
+ apr_brigade_cleanup(tmpbb);
}
else
nvec++;
@@ -800,6 +808,7 @@
return rv;
}
+ apr_brigade_destroy(tmpbb);
return APR_SUCCESS;
}
diff --git a/modules/fcgid/fcgid_proc_win.c b/modules/fcgid/fcgid_proc_win.c
index 60b26a6..5b3b33a 100644
--- a/modules/fcgid/fcgid_proc_win.c
+++ b/modules/fcgid/fcgid_proc_win.c
@@ -380,19 +380,22 @@
apr_bucket *bucket_request;
apr_status_t rv;
DWORD transferred;
+ apr_bucket_brigade *tmpbb = apr_brigade_create(birgade_send->p,
+ birgade_send->bucket_alloc);
handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
- for (bucket_request = APR_BRIGADE_FIRST(birgade_send);
- bucket_request != APR_BRIGADE_SENTINEL(birgade_send);
- bucket_request = APR_BUCKET_NEXT(bucket_request))
- {
+ while (!APR_BRIGADE_EMPTY(birgade_send)) {
const char *write_buf;
apr_size_t write_buf_len;
apr_size_t has_write;
- if (APR_BUCKET_IS_METADATA(bucket_request))
+ bucket_request = APR_BRIGADE_FIRST(birgade_send);
+
+ if (APR_BUCKET_IS_METADATA(bucket_request)) {
+ apr_bucket_delete(bucket_request);
continue;
+ }
if ((rv = apr_bucket_read(bucket_request, &write_buf, &write_buf_len,
APR_BLOCK_READ)) != APR_SUCCESS) {
@@ -401,6 +404,9 @@
return rv;
}
+ APR_BUCKET_REMOVE(bucket_request);
+ APR_BRIGADE_INSERT_TAIL(tmpbb, bucket_request);
+
/* Write the buffer to fastcgi server */
has_write = 0;
while (has_write < write_buf_len) {
@@ -411,6 +417,7 @@
write_buf_len - has_write,
&byteswrite, &handle_info->overlap_write)) {
has_write += byteswrite;
+ apr_brigade_cleanup(tmpbb);
continue;
} else if ((rv = GetLastError()) != ERROR_IO_PENDING) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING,
@@ -437,6 +444,7 @@
return APR_ESPIPE;
}
has_write += transferred;
+ apr_brigade_cleanup(tmpbb);
continue;
} else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0,
@@ -448,6 +456,7 @@
}
}
+ apr_brigade_destroy(tmpbb);
return APR_SUCCESS;
}