Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changes-entries/mod_env_setenvfromfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*) mod_env: Add the SetEnvFromFile directive to set internal environment
variables from a file of name=value lines, read at configuration time.
[Cornel Isbiceanu <cisbiceanu adobe.com>]
66 changes: 65 additions & 1 deletion docs/manual/mod/mod_env.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,69 @@ SSI pages</description>
</usage>
</directivesynopsis>

</modulesynopsis>
<directivesynopsis>
<name>SetEnvFromFile</name>
<description>Sets environment variables from a file</description>
<syntax>SetEnvFromFile <var>file-path</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context></contextlist>
<compatibility>Available in version 2.4.70 and later.</compatibility>

<usage>
<p>Sets internal environment variables read from a file, which are then
available to Apache HTTP Server modules, and passed on to CGI scripts and
SSI pages. This is equivalent to a series of <directive
module="mod_env">SetEnv</directive> directives, one per variable, but keeps
the values in a separate file.</p>

<p>The <var>file-path</var> is either an absolute path or a path relative
to the <directive module="core">ServerRoot</directive>. The file is read
once when the configuration is parsed; changes to it take effect only after
the server is restarted.</p>

<p>Each line of the file has the form <code>name=value</code>. Blank lines
and lines beginning with <code>#</code> are ignored, and leading and
trailing whitespace is stripped. If a line contains no <code>=</code>, the
variable is set to an empty string. A line ending in a backslash
(<code>\</code>) is continued on the following line, just as in the main
configuration files.</p>

<example><title>Example</title>
<highlight language="config">
SetEnvFromFile "conf/app.env"
</highlight>
</example>

<example><title>Example file (<code>conf/app.env</code>)</title>
<highlight language="config">
# Application settings
APP_MODE=production
SPECIAL_PATH=/foo/bin
</highlight>
</example>

<note><p>As with <directive module="mod_env">SetEnv</directive>, the
variables are set <em>after</em> most early request processing directives
are run, such as access control and URI-to-filename mapping.</p>
</note>

<note type="warning"><title>Security</title>
<p>Unlike <directive module="mod_env">SetEnv</directive>, this directive
reads the <em>contents</em> of a file into the internal environment, where
they may be exposed through CGI, SSI, logging and other consumers. To
prevent an untrusted author from disclosing the contents of any file
readable by the server (for example configuration or credential files
elsewhere on the host), <directive>SetEnvFromFile</directive> is
<strong>not</strong> permitted in <code>.htaccess</code> files; it may only
be used in the main server configuration.</p>
</note>

</usage>

<seealso><a href="../env.html">Environment Variables</a></seealso>

<seealso><directive module="mod_env">SetEnv</directive></seealso>

</directivesynopsis>

</modulesynopsis>
56 changes: 56 additions & 0 deletions modules/metadata/mod_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,59 @@ static const char *add_env_module_vars_unset(cmd_parms *cmd, void *sconf_,
return NULL;
}

static const char *add_env_module_vars_from_file(cmd_parms *cmd, void *sconf_,
const char *arg)
{
env_dir_config_rec *sconf = sconf_;
const char *fname;
ap_configfile_t *file;
apr_status_t rv;
char line[MAX_STRING_LEN];

fname = ap_server_root_relative(cmd->temp_pool, arg);
if (!fname) {
return apr_pstrcat(cmd->pool, cmd->cmd->name,
": Invalid file path ", arg, NULL);
}

rv = ap_pcfg_openfile(&file, cmd->temp_pool, fname);
if (rv != APR_SUCCESS) {
return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
cmd->cmd->name, fname, &rv);
}

/* Each line is "name=value"; blank lines and '#' comments are ignored.
* ap_cfg_getline() strips surrounding whitespace and handles line
* continuations. Names are read at config time and stored in the same
* table used by SetEnv, so they merge and reach r->subprocess_env the
* same way.
*/
while (!ap_cfg_getline(line, sizeof(line), file)) {
const char *rest = line;
const char *name, *value;

if (line[0] == '#' || line[0] == '\0') {
continue;
}

name = ap_getword(cmd->pool, &rest, '=');
if (!name[0]) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
APLOGNO(10632) "%s: Skipping malformed line "
"(no variable name) in %s", cmd->cmd->name, fname);
continue;
}

/* rest points just past the '='; no '=' means an empty value. */
value = apr_pstrdup(cmd->pool, rest);
apr_table_setn(sconf->vars, name, value);
}

ap_cfg_closefile(file);

return NULL;
}

static const command_rec env_module_cmds[] =
{
AP_INIT_ITERATE("PassEnv", add_env_module_vars_passed, NULL,
Expand All @@ -154,6 +207,9 @@ AP_INIT_TAKE12("SetEnv", add_env_module_vars_set, NULL,
OR_FILEINFO, "an environment variable name and optional value to pass to CGI."),
AP_INIT_ITERATE("UnsetEnv", add_env_module_vars_unset, NULL,
OR_FILEINFO, "a list of variables to remove from the CGI environment."),
AP_INIT_TAKE1("SetEnvFromFile", add_env_module_vars_from_file, NULL,
RSRC_CONF | ACCESS_CONF,
"the path to a file of name=value lines to pass to CGI."),
{NULL},
};

Expand Down
3 changes: 2 additions & 1 deletion test/modules/metadata/test_002_setenvfromfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from pyhttpd.backport import skip_not_backported
from pyhttpd.conf import HttpdConf

pytestmark = skip_not_backported("r1938506", "SetEnvFromFile")
pytestmark = skip_not_backported("r1938506", "SetEnvFromFile",
backported_in="2.4.70")


def _write_ssi_echo(path, names):
Expand Down
Loading