Commit 290049e7 authored by Nick Kew's avatar Nick Kew
Browse files

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
parent 17983218
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.2.12

  *) mod_ext_filter: fix error handling when the filter prog fails to start,
     and introduce an onfail configuration option to abort the request
     or to remove the broken filter and continue.
     PR 41120 [Nick Kew]

  *) mod_include: support generating non-ASCII characters as entities in SSI
     PR 25202 [Nick Kew] 

+0 −7
Original line number Diff line number Diff line
@@ -86,13 +86,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
  [ start all new proposals below, under PATCHES PROPOSED. ]

  * mod_ext_filter: fix error handling when the filter prog fails to start.
    PR 41120
    http://svn.apache.org/viewvc?view=rev&revision=731358
    http://svn.apache.org/viewvc?view=rev&revision=731388
    http://svn.apache.org/viewvc?view=rev&revision=731594
    +1: niq, rpluem, covener

PATCHES PROPOSED TO BACKPORT FROM TRUNK:
  [ New proposals should be added at the end of the list ]

+6 −0
Original line number Diff line number Diff line
@@ -340,6 +340,12 @@ delivery to the client</description>
      messages written to standard error by the external filter
      program will be saved in the Apache error log.
      <code>NoLogStderr</code> disables this feature.</dd>

      <dt><code>Onfail=[abort|remove]</code> (new in httpd version 2.2.12).</dt>
      <dd>Determines how to proceed if the external filter program
      cannot be started.  With <code>abort</code> (the default value)
      the request will be aborted.  With <code>remove</code>, the
      filter is removed and the request continues without it.</dd>
    </dl>

    <example><title>Example</title>
+54 −6
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ typedef struct ef_filter_t {
typedef struct ef_dir_t {
    int debug;
    int log_stderr;
    int onfail;
} ef_dir_t;

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

#define DBGLVL_SHOWOPTIONS         1
#define DBGLVL_ERRORCHECK          2
#define DBGLVL_GORY                9

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

    dc->debug = -1;
    dc->log_stderr = -1;
    dc->onfail = -1;

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

    if (over->onfail != -1) {   /* if admin coded something... */
        a->onfail = over->onfail;
    }
    else {
        a->onfail = base->onfail;
    }

    return a;
}

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

    if (dc->debug >= DBGLVL_ERRORCHECK) {
    rc = apr_procattr_error_check_set(ctx->procattr, 1);
        ap_assert(rc == APR_SUCCESS);
    if (rc != APR_SUCCESS) {
        return rc;
    }

    /* 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)

    if (!ctx) {
        if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
            return rv;
            ctx = f->ctx;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          "can't initialise output filter %s: %s",
                          f->frec->name,
                          (ctx->dc->onfail == 1) ? "removing" : "aborting");
            ap_remove_output_filter(f);
            if (ctx->dc->onfail == 1) {
                return ap_pass_brigade(f->next, bb);
            }
            else {
                apr_bucket *e;
                f->r->status_line = "500 Internal Server Error";

                apr_brigade_cleanup(bb);
                e = ap_bucket_error_create(HTTP_INTERNAL_SERVER_ERROR,
                                           NULL, r->pool,
                                           f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                e = apr_bucket_eos_create(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                ap_pass_brigade(f->next, bb);
                return AP_FILTER_ERROR;
            }
        }
        ctx = f->ctx;
    }
@@ -886,7 +922,19 @@ static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,

    if (!ctx) {
        if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
            return rv;
            ctx = f->ctx;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                          "can't initialise input filter %s: %s",
                          f->frec->name,
                          (ctx->dc->onfail == 1) ? "removing" : "aborting");
            ap_remove_input_filter(f);
            if (ctx->dc->onfail == 1) {
                return ap_get_brigade(f->next, bb, mode, block, readbytes);
            }
            else {
                f->r->status = HTTP_INTERNAL_SERVER_ERROR;
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
        ctx = f->ctx;
    }