Node.js and Apache per-request environment variables
Relevant selection for this article:
If you are using Passenger in its Apache integration mode, then you may be aware of the fact that Apache supports per-request environment variables. This page explains how Passenger passes per-request environment variables to the application.
This page is not talking about system environment variables!
There is a difference between operating system-level environment variables (which are controlled by the OS) and per-request environment variables (which are controlled by Apache). This page is only talking about the latter. If you are looking for information about OS-level environment variables, please refer to About environment variables. Refer to the Apache documentation to understand the differences.
Table of contents
- Loading...
Examples of per-request environment variables
Per-request environment variables are set by various Apache features and Apache modules. Here are some examples:
- Values set by Shibboleth, the identity federation Apache module.
- Values set by the RewriteRule
E
flag (provided bymod_rewrite
). - Values set by the SSLOptions StdEnvVars configuration option (provided by
mod_ssl
). - Values set by the Apache SetEnv directive (provided by
mod_env
). These values are static (hardcoded into the configuration file) and do not change on a per-request basis.
Please refer to Apache's documentation to learn more.
How Node.js apps can access per-request environment variables
Secure HTTP header: !~Passenger-Envvars
Since version 5.0.21, per-request environment variables can be accessed through the secure HTTP header named !~Passenger-Envvars
. This header contains an encoded dump of per-request environment variables.
The encoding is in the following format:
base64("key1\0value1\0key2\0value2\0")
In other words, all keys and values are appended into a single string, with NULL separators. The entire result is then base64'ed.
Suppose that your site is using SSL, and that you that SSLOptions StdEnvVars
enabled. You can access the SSL_SESSION_ID
environment variable as follows:
function parseEnvvarDump(dump) {
var ary = dump.split("\0");
var result = {};
var i;
for (i = 0; i < ary.length - 1; i += 2) {
result[ary[i]] = ary[i + 1];
}
return result;
}
var envvarB64 = req.headers['!~passenger-envvars'];
var envvarDump = new Buffer(envvarB64, 'base64').toString('binary');
var env = parseEnvvarDump(envvarDump);
console.log(env.SSL_SESSION_ID); // Prints some session ID value
The process.env
object
When Passenger handles a request and decides to spawn a new application process, Passenger will store the values of any per-request environment variables into OS-level environment variables. This is only done once per application process, and only when the application process is spawned.
This is primarily useful for ensuring that the SetEnv
directive works as expected. For example, suppose that you have this in your Apache configuration file:
SetEnv APP_NAME mydemoapp
You can then access APP_NAME
using process.env
, which is a mechanism in Node.js for accessing OS-level environment variables:
console.log(process.env.APP_NAME); // Prints: mydemoapp
There are two important caveats to be aware of:
process.env
does not change, so it must not be used for accessing per-request environment variables whose values may change on a per-request basis. For example, do not callprocess.env.SSL_SESSION_ID
becauseSSL_SESSION_ID
changes on a per-client basis.- If Passenger spawns an application process, but not as part of handling a request, then that application process will not have per-request environment variables stored inside OS-level environment variables.