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

📄 mod_setenvif.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* if the last entry has an identical headername and regex then     * merge with it     */    i = sconf->conditionals->nelts - 1;    icase = cmd->info == ICASE_MAGIC;    if (i < 0        || entries[i].name != fname        || entries[i].icase != icase        || strcmp(entries[i].regex, regex)) {        /* no match, create a new entry */        new = apr_array_push(sconf->conditionals);        new->name = fname;        new->regex = regex;        new->icase = icase;        if ((simple_pattern = non_regex_pattern(cmd->pool, regex))) {            new->pattern = apr_strmatch_precompile(cmd->pool,                                                   simple_pattern, !icase);            if (new->pattern == NULL) {                return apr_pstrcat(cmd->pool, cmd->cmd->name,                                   " pattern could not be compiled.", NULL);            }            new->preg = NULL;        }        else {            new->preg = ap_pregcomp(cmd->pool, regex,                                    (REG_EXTENDED | (icase ? REG_ICASE : 0)));            if (new->preg == NULL) {                return apr_pstrcat(cmd->pool, cmd->cmd->name,                                   " regex could not be compiled.", NULL);            }            new->pattern = NULL;        }        new->features = apr_table_make(cmd->pool, 2);        if (!strcasecmp(fname, "remote_addr")) {            new->special_type = SPECIAL_REMOTE_ADDR;        }        else if (!strcasecmp(fname, "remote_host")) {            new->special_type = SPECIAL_REMOTE_HOST;        }        else if (!strcasecmp(fname, "request_uri")) {            new->special_type = SPECIAL_REQUEST_URI;        }        else if (!strcasecmp(fname, "request_method")) {            new->special_type = SPECIAL_REQUEST_METHOD;        }        else if (!strcasecmp(fname, "request_protocol")) {            new->special_type = SPECIAL_REQUEST_PROTOCOL;        }        else if (!strcasecmp(fname, "server_addr")) {            new->special_type = SPECIAL_SERVER_ADDR;        }        else {            new->special_type = SPECIAL_NOT;            /* Handle fname as a regular expression.             * If fname a simple header string, identify as such             * (new->pnamereg = NULL) to avoid the overhead of searching             * through headers_in for a regex match.             */            if (is_header_regex(cmd->pool, fname)) {                new->pnamereg = ap_pregcomp(cmd->pool, fname,                                            (REG_EXTENDED | REG_NOSUB                                             | (icase ? REG_ICASE : 0)));                if (new->pnamereg == NULL)                    return apr_pstrcat(cmd->pool, cmd->cmd->name,                                       "Header name regex could not be "                                       "compiled.", NULL);            }            else {                new->pnamereg = NULL;            }        }    }    else {        new = &entries[i];    }    for ( ; ; ) {        feature = ap_getword_conf(cmd->pool, &args);        if (!*feature) {            break;        }        beenhere++;        var = ap_getword(cmd->pool, &feature, '=');        if (*feature) {            apr_table_setn(new->features, var, feature);        }        else if (*var == '!') {            apr_table_setn(new->features, var + 1, "!");        }        else {            apr_table_setn(new->features, var, "1");        }    }    if (!beenhere) {        return apr_pstrcat(cmd->pool, "Missing envariable expression for ",                           cmd->cmd->name, NULL);    }    return NULL;}static const char *add_setenvif(cmd_parms *cmd, void *mconfig,				const char *args){    char *fname;    /* get header name */    fname = ap_getword_conf(cmd->pool, &args);    if (!*fname) {        return apr_pstrcat(cmd->pool, "Missing header-field name for ",                           cmd->cmd->name, NULL);    }    return add_setenvif_core(cmd, mconfig, fname, args);}/* * This routine handles the BrowserMatch* directives.  It simply turns around * and feeds them, with the appropriate embellishments, to the general-purpose * command handler. */static const char *add_browser(cmd_parms *cmd, void *mconfig, const char *args){    return add_setenvif_core(cmd, mconfig, "User-Agent", args);}static const command_rec setenvif_module_cmds[] ={    AP_INIT_RAW_ARGS("SetEnvIf", add_setenvif, NULL, OR_FILEINFO,                     "A header-name, regex and a list of variables."),    AP_INIT_RAW_ARGS("SetEnvIfNoCase", add_setenvif, ICASE_MAGIC, OR_FILEINFO,                     "a header-name, regex and a list of variables."),    AP_INIT_RAW_ARGS("BrowserMatch", add_browser, NULL, OR_FILEINFO,                     "A browser regex and a list of variables."),    AP_INIT_RAW_ARGS("BrowserMatchNoCase", add_browser, ICASE_MAGIC,                     OR_FILEINFO,                     "A browser regex and a list of variables."),    { NULL },};/* * This routine gets called at two different points in request processing: * once before the URI has been translated (during the post-read-request * phase) and once after (during the header-parse phase).  We use different * config records for the two different calls to reduce overhead (by not * re-doing the server-wide settings during directory processing), and * signal which call it is by having the earlier one pass a flag to the * later one. */static int match_headers(request_rec *r){    sei_cfg_rec *sconf;    sei_entry *entries;    const apr_table_entry_t *elts;    const char *val;    apr_size_t val_len = 0;    int i, j;    char *last_name;    regmatch_t regm[AP_MAX_REG_MATCH];    if (!ap_get_module_config(r->request_config, &setenvif_module)) {        ap_set_module_config(r->request_config, &setenvif_module,                             SEI_MAGIC_HEIRLOOM);        sconf  = (sei_cfg_rec *) ap_get_module_config(r->server->module_config,                                                      &setenvif_module);    }    else {        sconf = (sei_cfg_rec *) ap_get_module_config(r->per_dir_config,                                                     &setenvif_module);    }    entries = (sei_entry *) sconf->conditionals->elts;    last_name = NULL;    val = NULL;    for (i = 0; i < sconf->conditionals->nelts; ++i) {        sei_entry *b = &entries[i];        /* Optimize the case where a bunch of directives in a row use the         * same header.  Remember we don't need to strcmp the two header         * names because we made sure the pointers were equal during         * configuration.         */        if (b->name != last_name) {            last_name = b->name;            switch (b->special_type) {            case SPECIAL_REMOTE_ADDR:                val = r->connection->remote_ip;                break;            case SPECIAL_SERVER_ADDR:                val = r->connection->local_ip;                break;            case SPECIAL_REMOTE_HOST:                val =  ap_get_remote_host(r->connection, r->per_dir_config,                                          REMOTE_NAME, NULL);                break;            case SPECIAL_REQUEST_URI:                val = r->uri;                break;            case SPECIAL_REQUEST_METHOD:                val = r->method;                break;            case SPECIAL_REQUEST_PROTOCOL:                val = r->protocol;                break;            case SPECIAL_NOT:                if (b->pnamereg) {                    /* Matching headers_in against a regex. Iterate through                     * the headers_in until we find a match or run out of                     * headers.                     */                    const apr_array_header_t                        *arr = apr_table_elts(r->headers_in);                    elts = (const apr_table_entry_t *) arr->elts;                    val = NULL;                    for (j = 0; j < arr->nelts; ++j) {                        if (!ap_regexec(b->pnamereg, elts[j].key, 0, NULL, 0)) {                             val = elts[j].val;                        }                    }                }                else {                    /* Not matching against a regex */                    val = apr_table_get(r->headers_in, b->name);                    if (val == NULL) {                        val = apr_table_get(r->subprocess_env, b->name);                    }                }            }            val_len = val ? strlen(val) : 0;        }        /*         * A NULL value indicates that the header field or special entity         * wasn't present or is undefined.  Represent that as an empty string         * so that REs like "^$" will work and allow envariable setting         * based on missing or empty field.         */        if (val == NULL) {            val = "";            val_len = 0;        }        if ((b->pattern && apr_strmatch(b->pattern, val, val_len)) ||            (!b->pattern && !ap_regexec(b->preg, val, AP_MAX_REG_MATCH, regm,                                        0))) {            const apr_array_header_t *arr = apr_table_elts(b->features);            elts = (const apr_table_entry_t *) arr->elts;            for (j = 0; j < arr->nelts; ++j) {                if (*(elts[j].val) == '!') {                    apr_table_unset(r->subprocess_env, elts[j].key);                }                else {                    if (!b->pattern) {                        char *replaced = ap_pregsub(r->pool, elts[j].val, val,                                                    AP_MAX_REG_MATCH, regm);                        if (replaced) {                            apr_table_setn(r->subprocess_env, elts[j].key,                                           replaced);                        }                    }                    else {                        apr_table_setn(r->subprocess_env, elts[j].key,                                       elts[j].val);                    }                }            }        }    }    return DECLINED;}static void register_hooks(apr_pool_t *p){    ap_hook_header_parser(match_headers, NULL, NULL, APR_HOOK_MIDDLE);    ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_MIDDLE);}module AP_MODULE_DECLARE_DATA setenvif_module ={    STANDARD20_MODULE_STUFF,    create_setenvif_config_dir, /* dir config creater */    merge_setenvif_config,      /* dir merger --- default is to override */    create_setenvif_config_svr, /* server config */    merge_setenvif_config,      /* merge server configs */    setenvif_module_cmds,       /* command apr_table_t */    register_hooks		/* register hooks */};

⌨️ 快捷键说明

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