--- apache_1.3.28/src/modules/standard/mod_setenvif.c 2003-02-04 02:13:29.000000000 +0900 +++ mod_setenvif.c 2003-09-21 08:05:51.000000000 +0900 @@ -117,11 +117,24 @@ * SetEnvIf remote_addr (127.0.0.1|192.168.10.) LOCAL */ +/* + * SetEnvIfAll and SetEnvIfEither were added by Nakamura Minoru + * in Sep 20, 2003. + * + * Usage: + * + * SetEnvIfAll name value expr1 [expr2 expr3 ...] + * SetEnvIfEither name value epxr1 [epxr2 epxr3 ...] + * + */ + #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" +#define EXTEND_IFALLL + enum special { SPECIAL_NOT, SPECIAL_REMOTE_ADDR, @@ -141,12 +154,19 @@ enum special, special_type,4); unsigned icase : 1; /* ignoring case? */ +#ifdef EXTEND_IFALLL + unsigned is_extend : 1; /* ignoring case? */ + unsigned is_and : 1; /* ignoring case? */ + char* value; + table* vars; +#endif EXTEND_IFALLL } sei_entry; typedef struct { array_header *conditionals; } sei_cfg_rec; + module MODULE_VAR_EXPORT setenvif_module; /* @@ -193,6 +213,13 @@ #define ICASE_MAGIC ((void *)(&setenvif_module)) #define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag" +#ifdef EXTEND_IFALLL +#define COND_IF_ALL_VARS 1 +#define COND_IF_EITHER_VARS 0 +const char* keyword_defined = "1"; +const char* keyword_undefined = "!"; +#endif EXTEND_IFALLL + static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, char *fname, const char *args) { @@ -255,6 +282,9 @@ new->name = fname; new->regex = regex; new->icase = icase; +#ifdef EXTEND_IFALLL + new->is_extend = 0; +#endif EXTEND_IFALLL new->preg = ap_pregcomp(cmd->pool, regex, (REG_EXTENDED | REG_NOSUB | (icase ? REG_ICASE : 0))); @@ -344,6 +374,95 @@ return add_setenvif_core(cmd, mconfig, "User-Agent", args); } +#ifdef EXTEND_IFALLL +static const char *add_setenvifall_core(cmd_parms* cmd, + int is_and, + void* mconfig, + char* fname, + const char *args) +{ + sei_cfg_rec* sconf; + sei_entry* entries; + int i; + int beenhere = 0; + int perdir; + char* arg; + + sei_entry *new = NULL; + + perdir = (cmd->path != NULL); + sconf = perdir ? + (sei_cfg_rec *) mconfig : + (sei_cfg_rec *) ap_get_module_config(cmd->server->module_config, + &setenvif_module); + + entries = (sei_entry *) sconf->conditionals->elts; + + if( new == NULL ){ + /* i = sconf->conditionals->nelts - 1; */ + new = ap_push_array(sconf->conditionals); + new->name = fname; + new->is_extend = 1; + new->is_and = is_and ; + new->vars = ap_make_table(cmd->pool, 2); + } + + arg = ap_getword_conf(cmd->pool, &args); + if( !*arg ){ + return ap_pstrcat(cmd->pool, "Missing envariable expression for ", + cmd->cmd->name, NULL); + } + new->value = arg ; + + for ( ; ; ) { + char* arg = ap_getword_conf(cmd->pool, &args); + if (!*arg) { + break; + } + beenhere++; + + if (*arg == '!') { + ap_table_setn(new->vars, arg + 1, keyword_undefined ); + } + else { + ap_table_setn(new->vars, arg, keyword_defined ); + } + } + + if (!beenhere) { + return ap_pstrcat(cmd->pool, "Missing envariable expression for ", + cmd->cmd->name, NULL); + } + + return NULL; +} + + +static const char *add_setenvifall(cmd_parms *cmd, void *mconfig, + const char *args) +{ + char* fname = ap_getword_conf(cmd->pool, &args); /* get header name */ + if (!*fname) { + return ap_pstrcat(cmd->pool, "Missing header-field name for ", + cmd->cmd->name, NULL); + } + + return add_setenvifall_core(cmd, COND_IF_ALL_VARS, mconfig, fname, args); +} + +static const char *add_setenvifeither(cmd_parms *cmd, void *mconfig, + const char *args) +{ + char* fname = ap_getword_conf(cmd->pool, &args); /* get header name */ + if (!*fname) { + return ap_pstrcat(cmd->pool, "Missing header-field name for ", + cmd->cmd->name, NULL); + } + + return add_setenvifall_core(cmd, COND_IF_EITHER_VARS, mconfig, fname, args); +} +#endif EXTEND_IFALL + static const command_rec setenvif_module_cmds[] = { { "SetEnvIf", add_setenvif, NULL, @@ -354,6 +473,10 @@ OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." }, { "BrowserMatchNoCase", add_browser, ICASE_MAGIC, OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." }, +#ifdef EXTEND_IFALLL + { "SetEnvIfAll", add_setenvifall, NULL, OR_FILEINFO, RAW_ARGS, "an environment variable name and conditions." }, + { "SetEnvIfEither", add_setenvifeither, NULL, OR_FILEINFO, RAW_ARGS, "an environment variable name and conditions." }, +#endif EXTEND_IFALL { NULL }, }; @@ -392,6 +515,58 @@ for (i = 0; i < sconf->conditionals->nelts; ++i) { sei_entry *b = &entries[i]; +#ifdef EXTEND_IFALLL + if( b->is_extend ){ + int flag ; + + array_header *arr = ap_table_elts(b->vars); + elts = (table_entry *) arr->elts; + + if( b->is_and == COND_IF_ALL_VARS ){ + /* SetEnvIfAll */ + flag = 1; + for (j = 0; j < arr->nelts; ++j) { + const char* var = elts[j].key; + const char* cond = elts[j].val; + const char* val = ap_table_get(r->headers_in, var); + + if (val == NULL) { + val = ap_table_get(r->subprocess_env, var); + } + + if( (cond == keyword_defined && val == NULL ) || + (cond != keyword_defined && val != NULL ) ){ + flag = 0; + break; + } + } + } else { + /* SetEnvIfEither */ + flag = 0; + for (j = 0; j < arr->nelts; ++j) { + const char* var = elts[j].key; + const char* cond = elts[j].val; + const char* val = ap_table_get(r->headers_in, var); + + if (val == NULL) { + val = ap_table_get(r->subprocess_env, var); + } + + if( (cond == keyword_defined && val != NULL ) || + (cond != keyword_defined && val == NULL ) ){ + flag = 1; + break; + } + } + } + if( flag ){ + /* set environment variable */ + ap_table_setn(r->subprocess_env, b->name, b->value); + } + continue; + } +#endif EXTEND_IFALLL + /* 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