⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_headers.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* handle RequestHeader and Header directive */static const char *header_inout_cmd(cmd_parms *cmd, void *indirconf,                              const char *action, const char *inhdr,                              const char *value, const char* envclause){    headers_conf *dirconf = indirconf;    const char *condition_var = NULL;    char *colon;    char *hdr = apr_pstrdup(cmd->pool, inhdr);    header_entry *new;    apr_array_header_t *fixup = (cmd->info == &hdr_in)        ? dirconf->fixup_in   : (cmd->info == &hdr_err)        ? 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, "add"))        new->action = hdr_add;    else if (!strcasecmp(action, "append"))        new->action = hdr_append;    else if (!strcasecmp(action, "unset"))        new->action = hdr_unset;    else if (!strcasecmp(action, "echo"))        new->action = hdr_echo;    else        return "first argument must be add, set, append, unset or echo.";    if (new->action == hdr_unset) {        if (value)            return "header unset takes two arguments";    }    else if (new->action == hdr_echo) {        regex_t *regex;        if (value)            return "Header echo takes two arguments";        else if (cmd->info == &hdr_in)            return "Header echo only valid on Header directive";        else {            regex = ap_pregcomp(cmd->pool, hdr, REG_EXTENDED | 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 (strncasecmp(envclause, "env=", 4) != 0) {            return "error: envclause should be in the form env=envar";        }        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 = apr_pstrdup(cmd->pool, &envclause[4]);    }        if ((colon = strchr(hdr, ':')))        *colon = '\0';    new->header = hdr;    new->condition_var = condition_var;    return parse_format_string(cmd->pool, new, value);}/* Handle all (xxx)Header directives */static const char *header_cmd(cmd_parms *cmd, void *indirconf,                              const char *args){    const char *s;    const char *action;    const char *hdr;    const char *val;    const char *envclause;    s = apr_pstrdup(cmd->pool, args);    action = ap_getword_conf(cmd->pool, &s);    if (cmd->info == &hdr_out) {        if (!strcasecmp(action, "always")) {            cmd->info = &hdr_err;            action = ap_getword_conf(cmd->pool, &s);        }        else if (!strcasecmp(action, "onsuccess")) {            action = ap_getword_conf(cmd->pool, &s);        }    }    hdr = ap_getword_conf(cmd->pool, &s);    val = *s ? ap_getword_conf(cmd->pool, &s) : NULL;    envclause = *s ? ap_getword_conf(cmd->pool, &s) : NULL;    if (*s) {        return apr_pstrcat(cmd->pool, cmd->cmd->name,                           " has too many arguments", NULL);    }    return header_inout_cmd(cmd, indirconf, action, hdr, val, 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. */static char* process_tags(header_entry *hdr, request_rec *r) {    int i;    const char *s;    char *str = NULL;    format_tag *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 int echo_header(echo_do *v, const char *key, const char *val){    /* If the input header (key) matches the regex, echo it intact to      * r->headers_out.     */    if (!ap_regexec(v->hdr->regex, key, 0, NULL, 0)) {        apr_table_add(v->r->headers_out, key, val);    }    return 1;}static void do_headers_fixup(request_rec *r, apr_table_t *headers,                             apr_array_header_t *fixup){    int i;    for (i = 0; i < fixup->nelts; ++i) {        header_entry *hdr = &((header_entry *) (fixup->elts))[i];        /* Have any conditional envar-controlled Header processing to do? */        if (hdr->condition_var) {            const char *envar = hdr->condition_var;            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_set:            apr_table_setn(headers, hdr->header, process_tags(hdr, r));            break;        case hdr_unset:            apr_table_unset(headers, hdr->header);            break;        case hdr_echo:        {            echo_do v;            v.r = r;            v.hdr = hdr;            apr_table_do((int (*) (void *, const char *, const char *))                          echo_header, (void *) &v, r->headers_in, NULL);            break;        }        }    }}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);    }}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_DEBUG, 0, f->r->server,                 "headers: ap_headers_output_filter()");    /* do the fixup */    do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err);    do_headers_fixup(f->r, f->r->headers_out, dirconf->fixup_out);    /* remove ourselves from the filter chain */    ap_remove_output_filter(f);    /* send the data up the stack */    return ap_pass_brigade(f->next,in);}static apr_status_t ap_headers_error_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_DEBUG, 0, f->r->server,                 "headers: ap_headers_error_filter()");    /* do the fixup */    do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err);    /* remove ourselves from the filter chain */    ap_remove_output_filter(f);    /* send the data up the stack */    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);    }    return DECLINED;}                                        static const command_rec headers_cmds[] ={    AP_INIT_RAW_ARGS("Header", header_cmd, &hdr_out, 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"),    {NULL}};static void register_format_tag_handler(apr_pool_t *p, char *tag, void *tag_handler, int def){    const void *h = apr_palloc(p, sizeof(h));    h = tag_handler;    apr_hash_set(format_tag_hash, tag, 1, h);}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(p, "D", (void*) header_request_duration, 0);    register_format_tag_handler(p, "t", (void*) header_request_time, 0);    register_format_tag_handler(p, "e", (void*) header_request_env_var, 0);    return OK;}static void register_hooks(apr_pool_t *p){    ap_hook_pre_config(header_pre_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_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);}module AP_MODULE_DECLARE_DATA headers_module ={    STANDARD20_MODULE_STUFF,    create_headers_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 */};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -