1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "apr_strings.h"
24 #include "ap_config.h"
26 #include "http_config.h"
27 #include "http_request.h"
32 apr_table_t
*unsetenv
;
35 module AP_MODULE_DECLARE_DATA env_module
;
37 static void *create_env_dir_config(apr_pool_t
*p
, char *dummy
)
39 env_dir_config_rec
*conf
= apr_palloc(p
, sizeof(*conf
));
41 conf
->vars
= apr_table_make(p
, 10);
42 conf
->unsetenv
= apr_table_make(p
, 10);
47 static void *merge_env_dir_configs(apr_pool_t
*p
, void *basev
, void *addv
)
49 env_dir_config_rec
*base
= basev
;
50 env_dir_config_rec
*add
= addv
;
51 env_dir_config_rec
*res
= apr_palloc(p
, sizeof(*res
));
53 const apr_table_entry_t
*elts
;
54 const apr_array_header_t
*arr
;
59 * res->vars = copy_table( p, base->vars );
60 * foreach $unsetenv ( @add->unsetenv )
61 * table_unset( res->vars, $unsetenv );
62 * foreach $element ( @add->vars )
63 * table_set( res->vars, $element.key, $element.val );
65 * add->unsetenv already removed the vars from add->vars,
66 * if they preceeded the UnsetEnv directive.
68 res
->vars
= apr_table_copy(p
, base
->vars
);
71 arr
= apr_table_elts(add
->unsetenv
);
73 elts
= (const apr_table_entry_t
*)arr
->elts
;
75 for (i
= 0; i
< arr
->nelts
; ++i
) {
76 apr_table_unset(res
->vars
, elts
[i
].key
);
80 arr
= apr_table_elts(add
->vars
);
82 elts
= (const apr_table_entry_t
*)arr
->elts
;
84 for (i
= 0; i
< arr
->nelts
; ++i
) {
85 apr_table_setn(res
->vars
, elts
[i
].key
, elts
[i
].val
);
92 static const char *add_env_module_vars_passed(cmd_parms
*cmd
, void *sconf_
,
95 env_dir_config_rec
*sconf
= sconf_
;
96 apr_table_t
*vars
= sconf
->vars
;
99 env_var
= getenv(arg
);
100 if (env_var
!= NULL
) {
101 apr_table_setn(vars
, arg
, apr_pstrdup(cmd
->pool
, env_var
));
104 ap_log_error(APLOG_MARK
, APLOG_WARNING
, 0, cmd
->server
,
105 "PassEnv variable %s was undefined", arg
);
111 static const char *add_env_module_vars_set(cmd_parms
*cmd
, void *sconf_
,
112 const char *name
, const char *value
)
114 env_dir_config_rec
*sconf
= sconf_
;
116 /* name is mandatory, value is optional. no value means
117 * set the variable to an empty string
119 apr_table_setn(sconf
->vars
, name
, value
? value
: "");
124 static const char *add_env_module_vars_unset(cmd_parms
*cmd
, void *sconf_
,
127 env_dir_config_rec
*sconf
= sconf_
;
129 /* Always UnsetEnv FOO in the same context as {Set,Pass}Env FOO
130 * only if this UnsetEnv follows the {Set,Pass}Env. The merge
131 * will only apply unsetenv to the parent env (main server).
133 apr_table_set(sconf
->unsetenv
, arg
, NULL
);
134 apr_table_unset(sconf
->vars
, arg
);
139 static const command_rec env_module_cmds
[] =
141 AP_INIT_ITERATE("PassEnv", add_env_module_vars_passed
, NULL
,
142 OR_FILEINFO
, "a list of environment variables to pass to CGI."),
143 AP_INIT_TAKE12("SetEnv", add_env_module_vars_set
, NULL
,
144 OR_FILEINFO
, "an environment variable name and optional value to pass to CGI."),
145 AP_INIT_ITERATE("UnsetEnv", add_env_module_vars_unset
, NULL
,
146 OR_FILEINFO
, "a list of variables to remove from the CGI environment."),
150 static int fixup_env_module(request_rec
*r
)
152 apr_table_t
*e
= r
->subprocess_env
;
153 env_dir_config_rec
*sconf
= ap_get_module_config(r
->per_dir_config
,
155 apr_table_t
*vars
= sconf
->vars
;
157 if (!apr_table_elts(sconf
->vars
)->nelts
)
160 r
->subprocess_env
= apr_table_overlay(r
->pool
, e
, vars
);
165 static void register_hooks(apr_pool_t
*p
)
167 ap_hook_fixups(fixup_env_module
, NULL
, NULL
, APR_HOOK_MIDDLE
);
170 module AP_MODULE_DECLARE_DATA env_module
=
172 STANDARD20_MODULE_STUFF
,
173 create_env_dir_config
, /* dir config creater */
174 merge_env_dir_configs
, /* dir merger --- default is to override */
175 NULL
, /* server config */
176 NULL
, /* merge server configs */
177 env_module_cmds
, /* command apr_table_t */
178 register_hooks
/* register hooks */