Skip to content

Commit 290049e

Browse files
author
Nick Kew
committed
Backport r731358/731388/731594
mod_ext_filter: introduce sane error handling when the filter program fails to start, including an onfail configuration option. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@732586 13f79535-47bb-0310-9956-ffa450edef68
1 parent 1798321 commit 290049e

4 files changed

Lines changed: 65 additions & 13 deletions

File tree

CHANGES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
-*- coding: utf-8 -*-
22
Changes with Apache 2.2.12
33

4+
*) mod_ext_filter: fix error handling when the filter prog fails to start,
5+
and introduce an onfail configuration option to abort the request
6+
or to remove the broken filter and continue.
7+
PR 41120 [Nick Kew]
8+
49
*) mod_include: support generating non-ASCII characters as entities in SSI
510
PR 25202 [Nick Kew]
611

STATUS

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,6 @@ RELEASE SHOWSTOPPERS:
8686
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
8787
[ start all new proposals below, under PATCHES PROPOSED. ]
8888

89-
* mod_ext_filter: fix error handling when the filter prog fails to start.
90-
PR 41120
91-
http://svn.apache.org/viewvc?view=rev&revision=731358
92-
http://svn.apache.org/viewvc?view=rev&revision=731388
93-
http://svn.apache.org/viewvc?view=rev&revision=731594
94-
+1: niq, rpluem, covener
95-
9689
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
9790
[ New proposals should be added at the end of the list ]
9891

docs/manual/mod/mod_ext_filter.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ delivery to the client</description>
340340
messages written to standard error by the external filter
341341
program will be saved in the Apache error log.
342342
<code>NoLogStderr</code> disables this feature.</dd>
343+
344+
<dt><code>Onfail=[abort|remove]</code> (new in httpd version 2.2.12).</dt>
345+
<dd>Determines how to proceed if the external filter program
346+
cannot be started. With <code>abort</code> (the default value)
347+
the request will be aborted. With <code>remove</code>, the
348+
filter is removed and the request continues without it.</dd>
343349
</dl>
344350

345351
<example><title>Example</title>

modules/filters/mod_ext_filter.c

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ typedef struct ef_filter_t {
5858
typedef struct ef_dir_t {
5959
int debug;
6060
int log_stderr;
61+
int onfail;
6162
} ef_dir_t;
6263

6364
typedef struct ef_ctx_t {
@@ -81,7 +82,6 @@ static apr_status_t ef_input_filter(ap_filter_t *, apr_bucket_brigade *,
8182
apr_off_t);
8283

8384
#define DBGLVL_SHOWOPTIONS 1
84-
#define DBGLVL_ERRORCHECK 2
8585
#define DBGLVL_GORY 9
8686

8787
#define ERRFN_USERDATA_KEY "EXTFILTCHILDERRFN"
@@ -92,6 +92,7 @@ static void *create_ef_dir_conf(apr_pool_t *p, char *dummy)
9292

9393
dc->debug = -1;
9494
dc->log_stderr = -1;
95+
dc->onfail = -1;
9596

9697
return dc;
9798
}
@@ -125,6 +126,13 @@ static void *merge_ef_dir_conf(apr_pool_t *p, void *basev, void *overridesv)
125126
a->log_stderr = base->log_stderr;
126127
}
127128

129+
if (over->onfail != -1) { /* if admin coded something... */
130+
a->onfail = over->onfail;
131+
}
132+
else {
133+
a->onfail = base->onfail;
134+
}
135+
128136
return a;
129137
}
130138

@@ -142,6 +150,12 @@ static const char *add_options(cmd_parms *cmd, void *in_dc,
142150
else if (!strcasecmp(arg, "NoLogStderr")) {
143151
dc->log_stderr = 0;
144152
}
153+
else if (!strcasecmp(arg, "Onfail=remove")) {
154+
dc->onfail = 1;
155+
}
156+
else if (!strcasecmp(arg, "Onfail=abort")) {
157+
dc->onfail = 0;
158+
}
145159
else {
146160
return apr_pstrcat(cmd->temp_pool,
147161
"Invalid ExtFilterOptions option: ",
@@ -449,9 +463,9 @@ static apr_status_t init_ext_filter_process(ap_filter_t *f)
449463
ap_assert(rc == APR_SUCCESS);
450464
apr_pool_userdata_set(f->r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ctx->p);
451465

452-
if (dc->debug >= DBGLVL_ERRORCHECK) {
453-
rc = apr_procattr_error_check_set(ctx->procattr, 1);
454-
ap_assert(rc == APR_SUCCESS);
466+
rc = apr_procattr_error_check_set(ctx->procattr, 1);
467+
if (rc != APR_SUCCESS) {
468+
return rc;
455469
}
456470

457471
/* add standard CGI variables as well as DOCUMENT_URI, DOCUMENT_PATH_INFO,
@@ -855,7 +869,29 @@ static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
855869

856870
if (!ctx) {
857871
if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
858-
return rv;
872+
ctx = f->ctx;
873+
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
874+
"can't initialise output filter %s: %s",
875+
f->frec->name,
876+
(ctx->dc->onfail == 1) ? "removing" : "aborting");
877+
ap_remove_output_filter(f);
878+
if (ctx->dc->onfail == 1) {
879+
return ap_pass_brigade(f->next, bb);
880+
}
881+
else {
882+
apr_bucket *e;
883+
f->r->status_line = "500 Internal Server Error";
884+
885+
apr_brigade_cleanup(bb);
886+
e = ap_bucket_error_create(HTTP_INTERNAL_SERVER_ERROR,
887+
NULL, r->pool,
888+
f->c->bucket_alloc);
889+
APR_BRIGADE_INSERT_TAIL(bb, e);
890+
e = apr_bucket_eos_create(f->c->bucket_alloc);
891+
APR_BRIGADE_INSERT_TAIL(bb, e);
892+
ap_pass_brigade(f->next, bb);
893+
return AP_FILTER_ERROR;
894+
}
859895
}
860896
ctx = f->ctx;
861897
}
@@ -886,7 +922,19 @@ static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
886922

887923
if (!ctx) {
888924
if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
889-
return rv;
925+
ctx = f->ctx;
926+
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
927+
"can't initialise input filter %s: %s",
928+
f->frec->name,
929+
(ctx->dc->onfail == 1) ? "removing" : "aborting");
930+
ap_remove_input_filter(f);
931+
if (ctx->dc->onfail == 1) {
932+
return ap_get_brigade(f->next, bb, mode, block, readbytes);
933+
}
934+
else {
935+
f->r->status = HTTP_INTERNAL_SERVER_ERROR;
936+
return HTTP_INTERNAL_SERVER_ERROR;
937+
}
890938
}
891939
ctx = f->ctx;
892940
}

0 commit comments

Comments
 (0)