]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_ext_filter: check exit status of filter processes
authorGiovanni Bechis <gbechis@apache.org>
Tue, 6 Jun 2023 22:02:37 +0000 (22:02 +0000)
committerGiovanni Bechis <gbechis@apache.org>
Tue, 6 Jun 2023 22:02:37 +0000 (22:02 +0000)
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

docs/log-message-tags/next-number
modules/filters/mod_ext_filter.c

index 1ba80e8f118e5701bc9812ad3bae75bc858ad601..22138604e1bfd63461b54165ef0bbc9c22ca87b6 100644 (file)
@@ -1 +1 @@
-10451
+10455
index cb987c3aa5d95b4eb4ed3fb22d5698f100270262..3944847c8de1daa273821e1ea3ee12462ea8b30a 100644 (file)
@@ -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) =