/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * mod_headers.c: Add/append/remove HTTP response headers
 *     Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996
 *
 * The Header directive can be used to add/replace/remove HTTP headers
 * within the response message.  The RequestHeader directive can be used
 * to add/replace/remove HTTP headers before a request message is processed.
 * Valid in both per-server and per-dir configurations.
 *
 * Syntax is:
 *
 *   Header action header value
 *   RequestHeader action header value
 *
 * Where action is one of:
 *     set    - set this header, replacing any old value
 *     add    - add this header, possible resulting in two or more
 *              headers with the same name
 *     append - append this text onto any existing header of this same
 *     merge  - merge this text onto any existing header of this same,
 *              avoiding duplicate values
 *     unset  - remove this header
 *      edit  - transform the header value according to a regexp
 *
 * Where action is unset, the third argument (value) should not be given.
 * The header name can include the colon, or not.
 *
 * The Header and RequestHeader directives can only be used where allowed
 * by the FileInfo override.
 *
 * When the request is processed, the header directives are processed in
 * this order: firstly, the main server, then the virtual server handling
 * this request (if any), then any <Directory> sections (working downwards
 * from the root dir), then an <Location> sections (working down from
 * shortest URL component), the any <File> sections. This order is
 * important if any 'set' or 'unset' actions are used. For example,
 * the following two directives have different effect if applied in
 * the reverse order:
 *
 *   Header append Author "John P. Doe"
 *   Header unset Author
 *
 * Examples:
 *
 *  To set the "Author" header, use
 *     Header add Author "John P. Doe"
 *
 *  To remove a header:
 *     Header unset Author
 *
 */

#include "apr.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_buckets.h"

#include "apr_hash.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"

#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_ssl.h"
#include "http_log.h"
#include "util_filter.h"
#include "http_protocol.h"
#include "ap_expr.h"

/* format_tag_hash is initialized during pre-config */
static apr_hash_t *format_tag_hash;

typedef enum {
    hdr_add = 'a',              /* add header (could mean multiple hdrs) */
    hdr_set = 's',              /* set (replace old value) */
    hdr_append = 'm',           /* append (merge into any old value) */
    hdr_merge = 'g',            /* merge (merge, but avoid duplicates) */
    hdr_unset = 'u',            /* unset header */
    hdr_echo = 'e',             /* echo headers from request to response */
    hdr_edit = 'r',             /* change value by regexp, match once */
    hdr_edit_r = 'R',           /* change value by regexp, everymatch */
    hdr_setifempty = 'i',       /* set value if header not already present*/
    hdr_note = 'n'              /* set value of header in a note */
} hdr_actions;

/*
 * magic cmd->info values
 */
static char hdr_in  = '0';  /* RequestHeader */
static char hdr_out_onsuccess = '1';  /* Header onsuccess */
static char hdr_out_always = '2';  /* Header always */

/* Callback function type. */
typedef const char *format_tag_fn(request_rec *r, char *a);

/*
 * There is an array of struct format_tag per Header/RequestHeader
 * config directive
 */
typedef struct {
    format_tag_fn *func;
    char *arg;
} format_tag;

/* 'Magic' condition_var value to run action in post_read_request */
static const char* condition_early = "early";
/*
 * There is one "header_entry" per Header/RequestHeader config directive
 */
typedef struct {
    hdr_actions action;
    const char *header;
    apr_array_header_t *ta;   /* Array of format_tag structs */
    ap_regex_t *regex;
    const char *condition_var;
    const char *subs;
    ap_expr_info_t *expr;
    ap_expr_info_t *expr_out;
} header_entry;

/* echo_do is used for Header echo to iterate through the request headers*/
typedef struct {
    request_rec *r;
    header_entry *hdr;
} echo_do;

/* edit_do is used for Header edit to iterate through the request headers */
typedef struct {
    request_rec *r;
    header_entry *hdr;
    apr_table_t *t;
} edit_do;

/*
 * headers_conf is our per-module configuration. This is used as both
 * a per-dir and per-server config
 */
typedef struct {
    apr_array_header_t *fixup_in;
    apr_array_header_t *fixup_out;
    apr_array_header_t *fixup_err;
} headers_conf;

module AP_MODULE_DECLARE_DATA headers_module;

/*
 * Tag formatting functions
 */
static const char *constant_item(request_rec *r, char *stuff)
{
    return stuff;
}
static const char *header_request_duration(request_rec *r, char *a)
{
    return apr_psprintf(r->pool, "D=%" APR_TIME_T_FMT,
                        (apr_time_now() - r->request_time));
}
static const char *header_request_time(request_rec *r, char *a)
{
    return apr_psprintf(r->pool, "t=%" APR_TIME_T_FMT, r->request_time);
}

/* unwrap_header returns HDR with any newlines converted into
 * whitespace if necessary. */
static const char *unwrap_header(apr_pool_t *p, const char *hdr)
{
    if (ap_strchr_c(hdr, APR_ASCII_LF) || ap_strchr_c(hdr, APR_ASCII_CR)) {
        char *ptr;

        hdr = ptr = apr_pstrdup(p, hdr);

        do {
            if (*ptr == APR_ASCII_LF || *ptr == APR_ASCII_CR)
                *ptr = APR_ASCII_BLANK;
        } while (*ptr++);
    }
    return hdr;
}

static const char *header_request_env_var(request_rec *r, char *a)
{
    const char *s = apr_table_get(r->subprocess_env,a);

    if (s)
        return unwrap_header(r->pool, s);
    else
        return "(null)";
}

static const char *header_request_ssl_var(request_rec *r, char *name)
{
    const char *val = ap_ssl_var_lookup(r->pool, r->server,
                                        r->connection, r, name);
    if (val && val[0])
        return unwrap_header(r->pool, val);
    else
        return "(null)";
}

static const char *header_request_loadavg(request_rec *r, char *a)
{
    ap_loadavg_t t;
    ap_get_loadavg(&t);
    return apr_psprintf(r->pool, "l=%.2f/%.2f/%.2f", t.loadavg,
                        t.loadavg5, t.loadavg15);
}

static const char *header_request_idle(request_rec *r, char *a)
{
    ap_sload_t t;
    ap_get_sload(&t);
    return apr_psprintf(r->pool, "i=%d", t.idle);
}

static const char *header_request_busy(request_rec *r, char *a)
{
    ap_sload_t t;
    ap_get_sload(&t);
    return apr_psprintf(r->pool, "b=%d", t.busy);
}

/*
 * Config routines
 */

static void *create_headers_dir_config(apr_pool_t *p, char *d)
{
    headers_conf *conf = apr_pcalloc(p, sizeof(*conf));

    conf->fixup_in = apr_array_make(p, 2, sizeof(header_entry));
    conf->fixup_out = apr_array_make(p, 2, sizeof(header_entry));
    conf->fixup_err = apr_array_make(p, 2, sizeof(header_entry));

    return conf;
}

static void *merge_headers_config(apr_pool_t *p, void *basev, void *overridesv)
{
    headers_conf *newconf = apr_pcalloc(p, sizeof(*newconf));
    headers_conf *base = basev;
    headers_conf *overrides = overridesv;

    newconf->fixup_in = apr_array_append(p, base->fixup_in,
                                         overrides->fixup_in);
    newconf->fixup_out = apr_array_append(p, base->fixup_out,
                                          overrides->fixup_out);
    newconf->fixup_err = apr_array_append(p, base->fixup_err,
                                          overrides->fixup_err);

    return newconf;
}

static char *parse_misc_string(apr_pool_t *p, format_tag *tag, const char **sa)
{
    const char *s;
    char *d;

    tag->func = constant_item;

    s = *sa;
    while (*s && *s != '%') {
        s++;
    }
    /*
     * This might allocate a few chars extra if there's a backslash
     * escape in the format string.
     */
    tag->arg = apr_palloc(p, s - *sa + 1);

    d = tag->arg;
    s = *sa;
    while (*s && *s != '%') {
        if (*s != '\\') {
            *d++ = *s++;
        }
        else {
            s++;
            switch (*s) {
            case '\\':
                *d++ = '\\';
                s++;
                break;
            case 'r':
                *d++ = '\r';
                s++;
                break;
            case 'n':
                *d++ = '\n';
                s++;
                break;
            case 't':
                *d++ = '\t';
                s++;
                break;
            default:
                /* copy verbatim */
                *d++ = '\\';
                /*
                 * Allow the loop to deal with this *s in the normal
                 * fashion so that it handles end of string etc.
                 * properly.
                 */
                break;
            }
        }
    }
    *d = '\0';

    *sa = s;
    return NULL;
}

static char *parse_format_tag(apr_pool_t *p, format_tag *tag, const char **sa)
{
    const char *s = *sa;
    const char * (*tag_handler)(request_rec *,char *);

    /* Handle string literal/conditionals */
    if (*s != '%') {
        return parse_misc_string(p, tag, sa);
    }
    s++; /* skip the % */

    /* Pass through %% or % at end of string as % */
    if ((*s == '%') || (*s == '\0')) {
        tag->func = constant_item;
        tag->arg = "%";
        if (*s)
            s++;
        *sa = s;
        return NULL;
    }

    tag->arg = "\0";
    /* grab the argument if there is one */
    if (*s == '{') {
        ++s;
        tag->arg = ap_getword(p,&s,'}');
    }

    tag_handler = (const char * (*)(request_rec *,char *))apr_hash_get(format_tag_hash, s++, 1);

    if (!tag_handler) {
        char dummy[2];
        dummy[0] = s[-1];
        dummy[1] = '\0';
        return apr_pstrcat(p, "Unrecognized header format %", dummy, NULL);
    }
    tag->func = tag_handler;

    *sa = s;
    return NULL;
}

/*
 * A format string consists of white space, text and optional format
 * tags in any order. E.g.,
 *
 * Header add MyHeader "Free form text %D %t more text"
 *
 * Decompose the format string into its tags. Each tag (struct format_tag)
 * contains a pointer to the function used to format the tag. Then save each
 * tag in the tag array anchored in the header_entry.
 */
static char *parse_format_string(cmd_parms *cmd, header_entry *hdr, const char *s)
{
    apr_pool_t *p = cmd->pool;
    char *res;

    /* No string to parse with unset and echo commands */
    if (hdr->action == hdr_unset || hdr->action == hdr_echo) {
        return NULL;
    }
    /* Tags are in the replacement value for edit */
    else if (hdr->action == hdr_edit || hdr->action == hdr_edit_r ) {
        s = hdr->subs;
    }

    if (!strncmp(s, "expr=", 5)) { 
        const char *err;
        hdr->expr_out = ap_expr_parse_cmd(cmd, s+5, 
                                          AP_EXPR_FLAG_STRING_RESULT,
                                          &err, NULL);
        if (err) {
            return apr_pstrcat(cmd->pool,
                    "Can't parse value expression : ", err, NULL);
        }
        return NULL;
    }

    hdr->ta = apr_array_make(p, 10, sizeof(format_tag));

    while (*s) {
        if ((res = parse_format_tag(p, (format_tag *) apr_array_push(hdr->ta), &s))) {
            return res;
        }
    }
    return NULL;
}

/* handle RequestHeader and Header directive */
static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd,
                                               void *indirconf,
                                               const char *action,
                                               const char *hdr,
                                               const char *value,
                                               const char *subs,
                                               const char *envclause)
{
    headers_conf *dirconf = indirconf;
    const char *condition_var = NULL;
    const char *colon;
    header_entry *new;
    ap_expr_info_t *expr = NULL;

    apr_array_header_t *fixup = (cmd->info == &hdr_in)
        ? dirconf->fixup_in   : (cmd->info == &hdr_out_always)
        ? dirconf->fixup_err
        : dirconf->fixup_out;

    new = (header_entry *) apr_array_push(fixup);

    if (!strcasecmp(action, "set"))
        new->action = hdr_set;
    else if (!strcasecmp(action, "setifempty"))
        new->action = hdr_setifempty;
    else if (!strcasecmp(action, "add"))
        new->action = hdr_add;
    else if (!strcasecmp(action, "append"))
        new->action = hdr_append;
    else if (!strcasecmp(action, "merge"))
        new->action = hdr_merge;
    else if (!strcasecmp(action, "unset"))
        new->action = hdr_unset;
    else if (!strcasecmp(action, "echo"))
        new->action = hdr_echo;
    else if (!strcasecmp(action, "edit"))
        new->action = hdr_edit;
    else if (!strcasecmp(action, "edit*"))
        new->action = hdr_edit_r;
    else if (!strcasecmp(action, "note"))
        new->action = hdr_note;
    else
        return "first argument must be 'add', 'set', 'setifempty', 'append', 'merge', "
               "'unset', 'echo', 'note', 'edit', or 'edit*'.";

    if (new->action == hdr_edit || new->action == hdr_edit_r) {
        if (subs == NULL) {
            return "Header edit requires a match and a substitution";
        }
        new->regex = ap_pregcomp(cmd->pool, value, AP_REG_EXTENDED);
        if (new->regex == NULL) {
            return "Header edit regex could not be compiled";
        }
        new->subs = subs;
    }
    else {
        /* there's no subs, so envclause is really that argument */
        if (envclause != NULL) {
            return "Too many arguments to directive";
        }
        envclause = subs;
    }
    if (new->action == hdr_unset) {
        if (value) {
            if (envclause) {
                return "header unset takes two arguments";
            }
            envclause = value;
            value = NULL;
        }
    }
    else if (new->action == hdr_echo) {
        ap_regex_t *regex;

        if (value) {
            if (envclause) {
                return "Header echo takes two arguments";
            }
            envclause = value;
            value = NULL;
        }
        if (cmd->info != &hdr_out_onsuccess && cmd->info != &hdr_out_always)
            return "Header echo only valid on Header "
                   "directives";
        else {
            regex = ap_pregcomp(cmd->pool, hdr, AP_REG_EXTENDED | AP_REG_NOSUB);
            if (regex == NULL) {
                return "Header echo regex could not be compiled";
            }
        }
        new->regex = regex;
    }
    else if (!value)
        return "Header requires three arguments";

    /* Handle the envclause on Header */
    if (envclause != NULL) {
        if (strcasecmp(envclause, "early") == 0) {
            condition_var = condition_early;
        }
        else if (strncasecmp(envclause, "env=", 4) == 0) {
            if ((envclause[4] == '\0')
                || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
                return "error: missing environment variable name. "
                    "envclause should be in the form env=envar ";
            }
            condition_var = envclause + 4;
        }
        else if (strncasecmp(envclause, "expr=", 5) == 0) {
            const char *err = NULL;
            expr = ap_expr_parse_cmd(cmd, envclause + 5, 0, &err, NULL);
            if (err) {
                return apr_pstrcat(cmd->pool,
                                   "Can't parse envclause/expression: ", err,
                                   NULL);
            }
        }
        else {
            return apr_pstrcat(cmd->pool, "Unknown parameter: ", envclause,
                               NULL);
        }
    }

    if ((colon = ap_strchr_c(hdr, ':'))) {
        hdr = apr_pstrmemdup(cmd->pool, hdr, colon-hdr);
    }

    new->header = hdr;
    new->condition_var = condition_var;
    new->expr = expr;

    return parse_format_string(cmd, new, value);
}

/* Handle all (xxx)Header directives */
static const char *header_cmd(cmd_parms *cmd, void *indirconf,
                              const char *args)
{
    const char *action;
    const char *hdr;
    const char *val;
    const char *envclause;
    const char *subs;

    action = ap_getword_conf(cmd->temp_pool, &args);
    if (cmd->info == &hdr_out_onsuccess) {
        if (!strcasecmp(action, "always")) {
            cmd->info = &hdr_out_always;
            action = ap_getword_conf(cmd->temp_pool, &args);
        }
        else if (!strcasecmp(action, "onsuccess")) {
            action = ap_getword_conf(cmd->temp_pool, &args);
        }
    }
    hdr = ap_getword_conf(cmd->pool, &args);
    val = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
    subs = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
    envclause = *args ? ap_getword_conf(cmd->pool, &args) : NULL;

    if (*args) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           " has too many arguments", NULL);
    }

    return header_inout_cmd(cmd, indirconf, action, hdr, val, subs, envclause);
}

/*
 * Process the tags in the format string. Tags may be format specifiers
 * (%D, %t, etc.), whitespace or text strings. For each tag, run the handler
 * (formatter) specific to the tag. Handlers return text strings.
 * Concatenate the return from each handler into one string that is
 * returned from this call.
 * If the original value was prefixed with "expr=", processing is
 * handled instead by ap_expr.
 */
static char* process_tags(header_entry *hdr, request_rec *r)
{
    int i;
    const char *s;
    char *str = NULL;
    format_tag *tag = NULL;

    if (hdr->expr_out) { 
        const char *err;
        const char *val;
        val = ap_expr_str_exec(r, hdr->expr_out, &err);
        if (err) { 
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02557)
                          "Can't evaluate value expression: %s", err);
            return "";
        }
        return apr_pstrdup(r->pool, val);
    }

    tag = (format_tag*) hdr->ta->elts;

    for (i = 0; i < hdr->ta->nelts; i++) {
        s = tag[i].func(r, tag[i].arg);
        if (str == NULL)
            str = apr_pstrdup(r->pool, s);
        else
            str = apr_pstrcat(r->pool, str, s, NULL);
    }
    return str ? str : "";
}
static const char *process_regexp(header_entry *hdr, const char *value,
                                  request_rec *r)
{
    ap_regmatch_t pmatch[AP_MAX_REG_MATCH];
    const char *subs;
    const char *remainder;
    char *ret;
    int diffsz;
    if (ap_regexec(hdr->regex, value, AP_MAX_REG_MATCH, pmatch, 0)) {
        /* no match, nothing to do */
        return value;
    }
    /* Process tags in the input string rather than the resulting
       * substitution to avoid surprises
       */
    subs = ap_pregsub(r->pool, process_tags(hdr, r), value, AP_MAX_REG_MATCH, pmatch);
    if (subs == NULL)
        return NULL;
    diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
    if (hdr->action == hdr_edit) {
        remainder = value + pmatch[0].rm_eo;
    }
    else { /* recurse to edit multiple matches if applicable */
        remainder = process_regexp(hdr, value + pmatch[0].rm_eo, r);
        if (remainder == NULL)
            return NULL;
        diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
    }
    ret = apr_palloc(r->pool, strlen(value) + 1 + diffsz);
    memcpy(ret, value, pmatch[0].rm_so);
    strcpy(ret + pmatch[0].rm_so, subs);
    strcat(ret, remainder);
    return ret;
}

static int echo_header(void *v, const char *key, const char *val)
{
    echo_do *ed = (echo_do *)v;

    /* If the input header (key) matches the regex, echo it intact to
     * r->headers_out.
     */
    if (!ap_regexec(ed->hdr->regex, key, 0, NULL, 0)) {
        apr_table_add(ed->r->headers_out, key, val);
    }

    return 1;
}

static int edit_header(void *v, const char *key, const char *val)
{
    edit_do *ed = (edit_do *)v;
    const char *repl = process_regexp(ed->hdr, val, ed->r);
    if (repl == NULL)
        return 0;

    apr_table_addn(ed->t, key, repl);
    return 1;
}

static int add_them_all(void *v, const char *key, const char *val)
{
    apr_table_t *headers = (apr_table_t *)v;

    apr_table_addn(headers, key, val);
    return 1;
}

static int do_headers_fixup(request_rec *r, apr_table_t *headers,
                             apr_array_header_t *fixup, int early)
{
    echo_do v;
    int i;
    const char *val;

    for (i = 0; i < fixup->nelts; ++i) {
        header_entry *hdr = &((header_entry *) (fixup->elts))[i];
        const char *envar = hdr->condition_var;

        /* ignore early headers in late calls */
        if (!early && (envar == condition_early)) {
            continue;
        }
        /* ignore late headers in early calls */
        else if (early && (envar != condition_early)) {
            continue;
        }
        /* Do we have an expression to evaluate? */
        else if (hdr->expr != NULL) {
            const char *err = NULL;
            int eval = ap_expr_exec(r, hdr->expr, &err);
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01501)
                              "Failed to evaluate expression (%s) - ignoring",
                              err);
            }
            else if (!eval) {
                continue;
            }
        }
        /* Have any conditional envar-controlled Header processing to do? */
        else if (envar && !early) {
            if (*envar != '!') {
                if (apr_table_get(r->subprocess_env, envar) == NULL)
                    continue;
            }
            else {
                if (apr_table_get(r->subprocess_env, &envar[1]) != NULL)
                    continue;
            }
        }

        switch (hdr->action) {
        case hdr_add:
            apr_table_addn(headers, hdr->header, process_tags(hdr, r));
            break;
        case hdr_append:
            apr_table_mergen(headers, hdr->header, process_tags(hdr, r));
            break;
        case hdr_merge:
            val = apr_table_get(headers, hdr->header);
            if (val == NULL) {
                apr_table_addn(headers, hdr->header, process_tags(hdr, r));
            } else {
                char *new_val = process_tags(hdr, r);
                apr_size_t new_val_len = strlen(new_val);
                int tok_found = 0;

                /* modified version of logic in ap_get_token() */
                while (*val) {
                    const char *tok_start;

                    while (apr_isspace(*val))
                        ++val;

                    tok_start = val;

                    while (*val && *val != ',') {
                        if (*val++ == '"')
                            while (*val)
                                if (*val++ == '"')
                                    break;
                    }

                    if (new_val_len == (apr_size_t)(val - tok_start)
                        && !strncmp(tok_start, new_val, new_val_len)) {
                        tok_found = 1;
                        break;
                    }

                    if (*val)
                        ++val;
                }

                if (!tok_found) {
                    apr_table_mergen(headers, hdr->header, new_val);
                }
            }
            break;
        case hdr_set:
            if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
                 ap_set_content_type(r, process_tags(hdr, r));
            }
            apr_table_setn(headers, hdr->header, process_tags(hdr, r));
            break;
        case hdr_setifempty:
            if (NULL == apr_table_get(headers, hdr->header)) {
                if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
                    ap_set_content_type(r, process_tags(hdr, r));
                }
                apr_table_setn(headers, hdr->header, process_tags(hdr, r));
            }
            break;
        case hdr_unset:
            apr_table_unset(headers, hdr->header);
            break;
        case hdr_echo:
            v.r = r;
            v.hdr = hdr;
            apr_table_do(echo_header, &v, r->headers_in, NULL);
            break;
        case hdr_edit:
        case hdr_edit_r:
            if (!ap_cstr_casecmp(hdr->header, "Content-Type") && r->content_type) {
                const char *repl = process_regexp(hdr, r->content_type, r);
                if (repl == NULL)
                    return 0;
                ap_set_content_type(r, repl);
            }
            if (apr_table_get(headers, hdr->header)) {
                edit_do ed;

                ed.r = r;
                ed.hdr = hdr;
                ed.t = apr_table_make(r->pool, 5);
                if (!apr_table_do(edit_header, (void *) &ed, headers,
                                  hdr->header, NULL))
                    return 0;
                apr_table_unset(headers, hdr->header);
                apr_table_do(add_them_all, (void *) headers, ed.t, NULL);
            }
            break;
        case hdr_note:
            apr_table_setn(r->notes, process_tags(hdr, r), apr_table_get(headers, hdr->header));
            break;
 
        }
    }
    return 1;
}

static void ap_headers_insert_output_filter(request_rec *r)
{
    headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
                                                 &headers_module);

    if (dirconf->fixup_out->nelts || dirconf->fixup_err->nelts) {
        ap_add_output_filter("FIXUP_HEADERS_OUT", NULL, r, r->connection);
    }
}

/*
 * Make sure our error-path filter is in place.
 */
static void ap_headers_insert_error_filter(request_rec *r)
{
    headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
                                                 &headers_module);

    if (dirconf->fixup_err->nelts) {
        ap_add_output_filter("FIXUP_HEADERS_ERR", NULL, r, r->connection);
    }
}

static apr_status_t ap_headers_output_filter(ap_filter_t *f,
                                             apr_bucket_brigade *in)
{
    headers_conf *dirconf = ap_get_module_config(f->r->per_dir_config,
                                                 &headers_module);

    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, f->r->server, APLOGNO(01502)
                 "headers: ap_headers_output_filter()");

    /* do the fixup */
    do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0);
    do_headers_fixup(f->r, f->r->headers_out, dirconf->fixup_out, 0);

    /* remove ourselves from the filter chain */
    ap_remove_output_filter(f);

    /* send the data up the stack */
    return ap_pass_brigade(f->next,in);
}

/*
 * Make sure we propagate any "Header always" settings on the error
 * path through http_protocol.c.
 */
static apr_status_t ap_headers_error_filter(ap_filter_t *f,
                                            apr_bucket_brigade *in)
{
    headers_conf *dirconf;

    dirconf = ap_get_module_config(f->r->per_dir_config,
                                    &headers_module);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server, APLOGNO(01503)
                 "headers: ap_headers_error_filter()");

    /*
     * Add any header fields defined by "Header always" to r->err_headers_out.
     * Server-wide first, then per-directory to allow overriding.
     */
    do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0);

    /*
     * We've done our bit; remove ourself from the filter chain so there's
     * no possibility we'll be called again.
     */
    ap_remove_output_filter(f);

    /*
     * Pass the buck.  (euro?)
     */
    return ap_pass_brigade(f->next, in);
}

static apr_status_t ap_headers_fixup(request_rec *r)
{
    headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
                                                 &headers_module);

    /* do the fixup */
    if (dirconf->fixup_in->nelts) {
        do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 0);
    }

    return DECLINED;
}
static apr_status_t ap_headers_early(request_rec *r)
{
    headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
                                                 &headers_module);

    /* do the fixup */
    if (dirconf->fixup_in->nelts) {
        if (!do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 1))
            goto err;
    }
    if (dirconf->fixup_err->nelts) {
        if (!do_headers_fixup(r, r->err_headers_out, dirconf->fixup_err, 1))
            goto err;
    }
    if (dirconf->fixup_out->nelts) {
        if (!do_headers_fixup(r, r->headers_out, dirconf->fixup_out, 1))
            goto err;
    }

    return DECLINED;
err:
    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01504)
                  "Regular expression replacement failed (replacement too long?)");
    return HTTP_INTERNAL_SERVER_ERROR;
}

static const command_rec headers_cmds[] =
{
    AP_INIT_RAW_ARGS("Header", header_cmd, &hdr_out_onsuccess, OR_FILEINFO,
                     "an optional condition, an action, header and value "
                     "followed by optional env clause"),
    AP_INIT_RAW_ARGS("RequestHeader", header_cmd, &hdr_in, OR_FILEINFO,
                     "an action, header and value followed by optional env "
                     "clause"),
    {NULL}
};

static void register_format_tag_handler(const char *tag,
                                        format_tag_fn *tag_handler)
{
    apr_hash_set(format_tag_hash, tag, 1, tag_handler);
}

static int header_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
{
    format_tag_hash = apr_hash_make(p);
    register_format_tag_handler("D", header_request_duration);
    register_format_tag_handler("t", header_request_time);
    register_format_tag_handler("e", header_request_env_var);
    register_format_tag_handler("s", header_request_ssl_var);
    register_format_tag_handler("l", header_request_loadavg);
    register_format_tag_handler("i", header_request_idle);
    register_format_tag_handler("b", header_request_busy);

    return OK;
}

static int header_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                              apr_pool_t *ptemp, server_rec *s)
{
    return OK;
}

static void register_hooks(apr_pool_t *p)
{
    ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter,
                              NULL, AP_FTYPE_CONTENT_SET);
    ap_register_output_filter("FIXUP_HEADERS_ERR", ap_headers_error_filter,
                              NULL, AP_FTYPE_CONTENT_SET);
    ap_hook_pre_config(header_pre_config,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_post_config(header_post_config,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_insert_filter(ap_headers_insert_output_filter, NULL, NULL, APR_HOOK_LAST);
    ap_hook_insert_error_filter(ap_headers_insert_error_filter,
                                NULL, NULL, APR_HOOK_LAST);
    ap_hook_fixups(ap_headers_fixup, NULL, NULL, APR_HOOK_LAST);
    ap_hook_post_read_request(ap_headers_early, NULL, NULL, APR_HOOK_FIRST);
}

AP_DECLARE_MODULE(headers) =
{
    STANDARD20_MODULE_STUFF,
    create_headers_dir_config,  /* dir config creater */
    merge_headers_config,       /* dir merger --- default is to override */
    NULL,                       /* server config */
    NULL,                       /* merge server configs */
    headers_cmds,               /* command apr_table_t */
    register_hooks              /* register hooks */
};
