summaryrefslogtreecommitdiffstats
path: root/modules/filters
diff options
context:
space:
mode:
authorGiovanni Bechis <gbechis@apache.org>2023-06-07 00:02:37 +0200
committerGiovanni Bechis <gbechis@apache.org>2023-06-07 00:02:37 +0200
commite466de0c0ca858be2d5bc1ebb446ef4b4dd0a4e6 (patch)
tree136475a861ca4244e228b32e131b721c26e217dd /modules/filters
parentthere is a separate `connectiontimeout` (diff)
downloadapache2-e466de0c0ca858be2d5bc1ebb446ef4b4dd0a4e6.tar.xz
apache2-e466de0c0ca858be2d5bc1ebb446ef4b4dd0a4e6.zip
mod_ext_filter: check exit status of filter processes
Whenever a filter process returns a non-zero exit status, or is killed by a signal, return a HTTP 500 error, and log the reason. Ran top-level make update-log-msg-tags to update APLOGNO numbers. Submitted by: Dimitry Andric <dimitry@unified-streaming.com> Github: closes #296 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1910267 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/filters')
-rw-r--r--modules/filters/mod_ext_filter.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/modules/filters/mod_ext_filter.c b/modules/filters/mod_ext_filter.c
index cb987c3aa5..3944847c8d 100644
--- a/modules/filters/mod_ext_filter.c
+++ b/modules/filters/mod_ext_filter.c
@@ -726,6 +726,40 @@ static apr_status_t pass_data_to_filter(ap_filter_t *f, const char *data,
return rv;
}
+/* check_filter_process_on_eos():
+ *
+ * if we hit end-of-stream, check the exit status of the filter process, and log
+ * an appropriate message if it failed
+ */
+static apr_status_t check_filter_process_on_eos(ef_ctx_t *ctx, request_rec *r)
+{
+ if (ctx->hit_eos) {
+ int exitcode;
+ apr_exit_why_e exitwhy;
+ apr_status_t waitret = apr_proc_wait(ctx->proc, &exitcode, &exitwhy,
+ APR_WAIT);
+ if (waitret != APR_CHILD_DONE) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, waitret, r, APLOGNO(10451)
+ "apr_proc_wait() failed, uri=%s", r->uri);
+ return waitret;
+ }
+ else if (exitwhy != APR_PROC_EXIT) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(10452)
+ "child process %s killed by signal %d, uri=%s",
+ ctx->filter->command, exitcode, r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ else if (exitcode != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(10453)
+ "child process %s exited with non-zero status %d, "
+ "uri=%s", ctx->filter->command, exitcode, r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ return APR_SUCCESS;
+}
+
/* ef_unified_filter:
*
* runs the bucket brigade bb through the filter and puts the result into
@@ -880,6 +914,11 @@ static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
if (rv != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01468)
"ef_unified_filter() failed");
+ return rv;
+ }
+
+ if ((rv = check_filter_process_on_eos(ctx, r)) != APR_SUCCESS) {
+ return rv;
}
if ((rv = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
@@ -939,7 +978,13 @@ static apr_status_t ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
}
rv = ef_unified_filter(f, bb);
- return rv;
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(10454)
+ "ef_unified_filter() failed");
+ return rv;
+ }
+
+ return check_filter_process_on_eos(ctx, f->r);
}
AP_DECLARE_MODULE(ext_filter) =