Working with Environment Variables
1. Setting Environment Variables
| Directive | Description | Values | Notes |
|---|---|---|---|
| SetEnv | Sets an environment variable for the current request | VAR_NAME value |
Can be used in .htaccess or server config |
| SetEnvIf | Sets an environment variable based on a condition | Condition VAR_NAME value |
Useful for conditional variable setting |
| PassEnv | Passes environment variables to CGI scripts | VAR_NAME |
Must be set in main server config |
Example: Setting Environment Variables
<IfModule mod_env.c>
SetEnv NODE_ENV production
SetEnv API_URL https://api.example.com
</IfModule>
Example: Conditional Variable Setting
<IfModule mod_env.c>
SetEnvIf User-Agent "Mobile" IS_MOBILE
SetEnvIf Request_URI "\.(jpg|png)$" IS_IMAGE
</IfModule>
2. Unsetting Environment Variables
| Directive | Description | Notes |
|---|---|---|
| SetEnvIf | Conditionally sets environment variables based on request attributes. | Use SetEnvIf with a regex that matches the variable to unset. |
| RemoveEnv | Removes an environment variable from the request environment. | Available in Apache 2.4+; removes the variable entirely from the environment. |
Example: Unsetting a Variable Using RemoveEnv
<VirtualHost *:80>
ServerName example.com
RemoveEnv HTTP_AUTHORIZATION
</VirtualHost>
Note:
RemoveEnv is the preferred method for unsetting environment variables in Apache 2.4 and later.
3. Passing System Variables
| Directive | Description | Values | Notes |
|---|---|---|---|
| SetEnv | Sets an environment variable for the current request | VAR_NAME value |
Can be used in .htaccess or server config |
| SetEnvIf | Sets an environment variable based on a condition | Condition VAR_NAME value |
Useful for conditional variable setting |
| PassEnv | Passes environment variables from the system to the server | VAR_NAME |
Must be set in the server config, not .htaccess |
Note: Environment variables set with
SetEnv are only available within the context of the Apache server and its modules. They do not affect the system environment.
4. Using Conditional Variables
| Variable | Condition | Description |
|---|---|---|
| ENV | ENV:VAR_NAME |
Accesses environment variables set by the OS or via SetEnv |
| SERVER | SERVER:VAR_NAME |
Accesses server variables like SERVER_NAME, SERVER_PORT |
| REQUEST | REQUEST:VAR_NAME |
Accesses request variables like REQUEST_METHOD, QUERY_STRING |
Example: Setting Environment Variables Based on Conditions
<IfDefine DEBUG>
SetEnv DEBUG_MODE "true"
</IfDefine>
<IfModule mod_rewrite.c>
RewriteCond %{ENV:DEBUG_MODE} "true"
RewriteRule ^/debug/(.*)$ /$1 [L]
</IfModule>
Example: Using Environment Variables in Rewrite Rules
SetEnv ENVIRONMENT "production"
<IfModule mod_rewrite.c>
RewriteCond %{ENV:ENVIRONMENT} "production"
RewriteRule ^/api/(.*)$ https://prod-api.example.com/$1 [R=301,L]
</IfModule>
Note: The
ENV variable is particularly useful for conditional logic in mod_rewrite and other modules that support environment variable expansion.
5. Setting Variables Based on Browser
| Variable | Source | Description | Notes |
|---|---|---|---|
| HTTP_USER_AGENT | Request Header |
User agent string from browser | Used to detect browser type and version |
| HTTP_ACCEPT_LANGUAGE | Request Header |
Browser's preferred language(s) | Used for localization and content negotiation |
| HTTP_ACCEPT_ENCODING | Request Header |
Supported content encoding types | Used for compression negotiation (e.g., gzip) |
| HTTP_ACCEPT_CHARSET | Request Header |
Supported character encodings | Deprecated in favor of Accept-Charset |
Example: Setting a Variable Based on User Agent
<If "%{HTTP_USER_AGENT} =~ /Chrome/">
SetEnv browser_family "Chrome"
</If>
<If "%{HTTP_USER_AGENT} =~ /Firefox/">
SetEnv browser_family "Firefox"
</If>
Note: The
HTTP_USER_AGENT variable can be unreliable for browser detection due to spoofing and varying formats across devices.
Browser Detection Approaches
- User-Agent Parsing: Relies on string matching; fragile and outdated
- Feature Detection: Uses JavaScript to detect capabilities; more reliable
- Server-Side Detection: Uses
SetEnvto set variables based on headers; useful for content negotiation
6. Setting Variables from Headers
| Directive | Description | Values | Notes |
|---|---|---|---|
| SetEnvIf | Sets environment variables based on HTTP headers or other conditions | Header-Name Value-Pattern Variable-Name |
Can use regex patterns in value matching |
| SetEnvIfExpr | Sets environment variables using expression syntax (more powerful) | Expression Variable-Name |
Supports complex conditional logic using expressions |
Example: Setting a variable based on User-Agent header
SetEnvIf User-Agent "^Mozilla/5.0" is_mozilla
Example: Setting a variable using expression syntax
SetEnvIfExpr "%{HTTP_USER_AGENT} =~ /Chrome/ && %{HTTP_ACCEPT} =~ /html/" is_chrome
Note: Environment variables set with
SetEnvIf or SetEnvIfExpr can be used in other directives like Condition or Redirect.
Warning: Be cautious with regex patterns in
SetEnvIf, as they can impact performance if not optimized.
Key Points
SetEnvIfis used to conditionally set environment variables based on HTTP headers.SetEnvIfExprallows for more complex logic using expressions.- Variables set can be used in other directives to control behavior dynamically.
7. Using Variables in Configuration Directives
| Variable | Usage | Description |
|---|---|---|
| %{ENV:variable_name} | SetEnvIf Request_URI "^/api/" API_REQUEST="true" |
Access environment variables set by SetEnv or SetEnvIf. |
| %{ENV:variable_name} | Redirect permanent /oldpath %{ENV:REDIRECT_URL} |
Use environment variables in directives like Redirect. |
Example: Setting and Using Environment Variables
<IfModule mod_env.c>
SetEnv MY_APP_ENV production
SetEnv API_VERSION v1
</IfModule>
<Location "/api">
SetEnv API_REQUEST true
RewriteRule ^/api/(.*)$ /api.php?version=%{ENV:API_VERSION}&request=$1 [QSA]
</Location>
Note: Environment variables set via
SetEnv or SetEnvIf can be accessed using the %{ENV:variable_name} syntax in configuration directives.
Warning: Variables set with
SetEnv are not available in the client's environment, only within the server context.
8. Logging Environment Variables
| Directive | Description | Default | Notes |
|---|---|---|---|
| SetEnv | Sets an environment variable for the current request | None | Can be used in .htaccess or server config |
| SetEnvIf | Sets an environment variable based on a condition | None | Condition can be based on user agent, IP address, etc. |
| PassEnv | Passes environment variables to CGI scripts | None | Must be set in the main server config or virtual host |
Example: Setting Environment Variables
<IfModule mod_env.c>
SetEnv MY_VAR "my_value"
SetEnv NODE_ENV production
</IfModule>
Example: Conditional Variable Setting
<IfModule mod_env.c>
SetEnvIf User-Agent "MSIE" is_ie
SetEnvIf User-Agent "Firefox" is_firefox
</IfModule>
Example: Logging Variables in Error Log
<IfModule mod_env.c>
SetEnv DEBUG_MODE 1
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 3
</IfModule>
Note: Environment variables set with
SetEnv are only available to the current request and do not persist across requests.
Warning: Be cautious when setting sensitive environment variables in configuration files that might be readable by users.
9. Accessing Variables in CGI Scripts
| Variable | Description | Example Value |
|---|---|---|
| HTTP_COOKIE | Client's cookie data | sessionid=abc123; user=john |
| QUERY_STRING | Query string from the URL | name=John&age=30 |
| REQUEST_METHOD | HTTP method used (GET, POST, etc.) | POST |
| CONTENT_TYPE | Content type of the request body | application/x-www-form-urlencoded |
| CONTENT_LENGTH | Length of the request body in bytes | 25 |
| REMOTE_ADDR | IP address of the client | 192.168.1.100 |
| SERVER_PROTOCOL | Protocol used (e.g., HTTP/1.1) | HTTP/1.1 |
| SERVER_SOFTWARE | Server software name and version | Apache/2.4.57 (Unix) |
Example: Reading CGI Environment Variables in Python
import os
# Read environment variables
query_string = os.environ.get('QUERY_STRING', '')
content_type = os.environ.get('CONTENT_TYPE', '')
remote_addr = os.environ.get('REMOTE_ADDR', '')
print(f"Query String: {query_string}")
print(f"Content Type: {content_type}")
print(f"Remote Address: {remote_addr}")
10. Using Variables in Rewrite Rules
| Variable | Description | Usage Example |
|---|---|---|
| %{REQUEST_URI} | Original URI requested by the client | RewriteRule ^old-page\.html$ %{REQUEST_URI} [R=301,L] |
| %{QUERY_STRING} | Query string from the request | RewriteRule ^search$ /results.php?query=%{QUERY_STRING} [L] |
| %{HTTP_HOST} | Host name from the request | RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] |
| %{REQUEST_METHOD} | HTTP method used (GET, POST, etc.) | RewriteRule ^api/.*$ /backend.php [E=method:%{REQUEST_METHOD}] |
| %{HTTPS} | Set to "on" if the request is HTTPS | RewriteCond %{HTTPS} off [NC] |
| %{ENV:VAR_NAME} | Access environment variable set by SetEnv or SetEnvIf | RewriteRule ^admin/.*$ /secure.php [E=admin:%{ENV:ADMIN_MODE}] |
Example: Redirecting Based on Query String
RewriteEngine On
RewriteCond %{QUERY_STRING} ^page=([0-9]+)$
RewriteRule ^old-page\.html$ /new-page.html?page=%1? [R=301,L]
Example: Setting Environment Variables Based on Host
RewriteEngine On
RewriteCond %{HTTP_HOST} ^api\.example\.com$ [NC]
RewriteRule ^.*$ /api/index.php [E=API_ENDPOINT:1,L]
Note: Variables in mod_rewrite rules are expanded at runtime, so they can be used for dynamic content manipulation.
11. Testing Environment Variables
| Command | Description | Example |
|---|---|---|
| echo $VAR_NAME | Prints the value of an environment variable | echo $PATH |
| env | Lists all environment variables | env | grep HOME |
| printenv | Prints the value of a specific environment variable | printenv USER |
Example: Setting and Using Environment Variables in Shell
export MY_VAR="Hello World"
echo $MY_VAR
printenv MY_VAR
Note: Changes to environment variables in a shell session only affect that session and child processes. To make changes permanent, they must be added to shell configuration files like
~/.bashrc or ~/.profile.
12. Understanding Variable Scope and Inheritance
| Variable | Scope | Inheritance | Description |
|---|---|---|---|
| SERVER_NAME | Global | Yes | Name of the server as specified in the ServerName directive. |
| REQUEST_URI | Request | No | The URI requested by the client. |
| QUERY_STRING | Request | No | The query string part of the URI. |
| DOCUMENT_ROOT | Global | Yes | The root directory of the server's document tree. |
| SCRIPT_FILENAME | Request | No | The full path to the script being executed. |
| PATH_INFO | Request | No | Additional path information passed to the script. |
Example: Setting and Using Environment Variables
SetEnv MY_APP_ENV production
SetEnv DB_HOST localhost
Note: Environment variables set via
SetEnv are available to CGI scripts and can be accessed through the standard environment variables in most programming languages.
Warning: Variables set with
SetEnv are not inherited by child processes in all systems. Ensure proper handling for cross-platform compatibility.