mod_setenvif

Overview

mod_setenvif module allows to set environment variables if specific parts of request match given regular expressions. These environment variables may be used by other parts of the server to make decisions about which actions to make.

Quick start

Enable gzip-compression for specified files in .htaccess

# enable compression
SetEnvIf (mime text/.*) and (mime application/x-javascript) gzip=9

Enable memory-based cache for *.asp files

# enable cache
SetEnvIfNoCase request_uri ^.*\.asp$ cache-enable=mem

Related articles and topics

Directives

Name Context Description
BrowserMatch S V D .h Sets environment variables conditional on HTTP User-Agent
BrowserMatchNoCase S V D .h Sets environment variables conditional on User-Agent regardless of case
SetEnvIf S V D .h Sets environment variables based on attributes of the request
SetEnvIfNoCase S V D .h Sets environment variables based on attributes of the request regardless of case

BrowserMatch

Sets environment variables conditional on HTTP User-Agent

Syntax

BrowserMatch regex [!]env-variable[=value] [[!]env-variable[=value]] [...] [late]

Description

BrowserMatch (special case of SetEnvIf directive) allows processing of environment variables depending on the value of User-Agent header.

Example

BrowserMatch MSIE !javascript

BrowserMatchNoCase

Sets environment variables conditional on User-Agent regardless of case

Syntax

BrowserMatchNoCase regex [!]env-variable[=value] [[!]env-variable[=value]] [...] [late]

Description

BrowserMatchNoCase directive (special case of SetEnvIfNoCase directive) has the same meaning as BrowserMatch directive, the only difference is that it performs case-insensitive matching.

Example

BrowserMatchNoCase mac platform=macintosh
BrowserMatchNoCase win platform=windows

SetEnvIf

Sets environment variables based on attributes of the request

Syntax

SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] [...] [late]

SetEnvIf directive defines environment variables based on the attributes of the request.

Attribute value may be one of the following:

  • HTTP request header field, e.g., Host , User-Agent , Referer , and Accept-Language . Regular expressions are possible.
  • Remote_Host — hostname (if available) of the client making the request;
  • Remote_Addr — IP address of the client making the request;
  • Server_Addr — IP address of the server that received the request;
  • Request_Method — method name (GET, POST, etc.);
  • Request_Protocol — name and version of the protocol that served the request (always "HTTP/1.1");
  • Request_URI — the resource requested by HTTP request; is usually
  • represented by a part of the URL after hosthame and without query string.
  • Query_String — the query string requested by HTTP request;
  • Mime Content-Type response header value. Note that not only MIME-type may be specified in the value. Please refer to HTTP protocol documentation to get more information.
  • Name of an environment variable in the list of those associated with the request. This allows SetEnvIf directives to test against the result of prior matches. Only those environment variables defined by earlier SetEnv[If[NoCase]] directives are available for testing in this manner. Earlier means above in current context or in broader context (e.g., server level). Environment variables will be processed only if none of request characteristics matched and regular expression was not used for attribute.
  • Server variables (supported only in Helicon Ape; Apache doesn't support this feature ).

regex argument represents regular expression. If the regex matches against the attribute, consequent arguments are processed.

The following arguments are used either to assign variable names to be set and values they will obtain or to unset existing variables.

Example:

#the value of varname will be set to 1 
SetEnvIf Host .* varname
#variable will be deleted
SetEnvIf Host .* !varname
#varname will be assigned 'value'
SetEnvIf Host .* varname=value

$1..$N constructions are also recognized, the values are taken from regex argument.

%{ENV_NAME}e format may be used in the name of environment variables to get the value of existing variables ( Apache doesn't support this feature ).

Example

SetEnvIf Host (.*) my-host=$1
BrowserMatch Mozilla/4\.[678] stop-old-stuff="Mozilla4.6-8 isn't allowed on %{my-host}e"
Header set Ban %{stop-old-stuff}e env=stop-old-stuff

Ban header will be created if the client browser is indentified as Mozilla/4.6-8 .

late argument allows to set variables after script execution. So the script couldn't see variables created with late argument. The argument is designed to modify environment in dependence with script actions (maybe additional HTTP headers will be added etc.). Apache doesn't support late argument.

If you use Mime argument, it will be processed after script execution because Content-Type header is not accessible earlier.

Example

#sets object_type variable if jpg image was requested
SetEnvIf Request_URI "\.jpg$" object_type=jpg

#sets ref_var variable if the request refers to somewhere on www.domain.com
SetEnvIf Referer www\.domain\.com ref_var

Example configuration mod_gzip

mod_gzip_on yes
SetEnvIf Mime ^text/html gzip=9
SetEnvIf Mime ^image/.* no-gzip
SetEnvIf Mime ^text/plain gzip

SetEnvIfNoCase

Sets environment variables based on attributes of the request regardless of case.

Syntax

SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] [...] [late]

SetEnvIfNoCase directive has the same meaning as SetEnvIf directive, the only difference is that it performs case-insensitive matching.

Example

#sets site variable if Host header includes sitename.com
SetEnvIfNoCase Host sitename\.com site=sitename

Extended expressions

This chapter is applicable only for Helicon Ape; Apache doesn't support this functionality .

General info

To extend and make management of server variables more flexible since build 1.0.0.15 Helicon Ape mod_setenvif module supports extended syntax that allows to join several conditions using trivial logical operators AND and OR.

Such expressions may be used in any mod_setenvif directive: SetEnvIf , SetEnvIfNoCase , BrowserMatch , BrowserMatchNoCase .

The general syntax of extended expressions is as follows:

SetEnvIf attribute1 regex1 OPERATION attribute2 regex2 ... attributeN regexN [!]env-variable[=value] [[!]env-variable[=value]] ... [late]

OPERATION may be either AND or OR that perform corresponding logical operations. Logical AND has the meaning of multiplication and OR means addition. It follows from this that AND has higher priority and will be processed earlier.

SetEnvIf request_uri ^/index\.php$ and query_string id=\d+ or host (?!www\.).* my-env

In this example my-env variable will be set if request URI matches ^index\.php$ AND query string matches id=\d+ , OR Host header value doesn't start with www . Boolean equivalent is: a AND b OR c .

Argument/regex pairs may be separated using statement parentheses .

SetEnvIf request_uri ^/index\.php$ and ( query_string id=\d+ or host (?!www\.).* ) my-env

In this example parentheses affect the logic. Now my-env variable will be set if request URI matches ^index\.php$ , AND query string matches id=\d+ OR Host value doesn't start with www . Boolean equivalent is: a AND (b OR c) .

Extended expressions also support negation (NOT). To negate a regex you must put a '!' character in front of it.

SetEnvIf (mime !image/gif) and (query_string id=\d+) gzip

In this situation GZIP compression will be enables (by gzip variable) if response MIME-type is NOT image/gif AND query string doesn't match id=\d+ .

Note! You can not negate a group of conditions inside parentheses.

Incorrect example:

SetEnvIf !(mime image/gif or mime application/.* or mime audio/.*) gzip

But this limitation may be easily bypassed in the following way.

Correct example:

SetEnvIf (mime !image/gif) and (mime !application/.*) and (mime !audio/.*) gzip

Important note regarding BrowserMatch , BrowserMatchNoCase directives

For BrowserMatch/BrowserMatchNoCase directives the first attribute is always User-Agent header, that's why the first value after directive name is NOT an attribute BUT a regex that will be matched against User-Agent header. The rest of the above guidelines are completely applicable to those directives.

BrowserMatch Mozilla/4\.[678] and mime image/jpeg gzip

Important note regarding matched/non-matched groups

Standard Apache mod_setenvif capabilities allow matching groups in regular expressions and then inserting these matches into the values of created environment variables. The same functionality is supported in Helicon Ape, but extended syntax has some peculiarities.

All groups are numbered left to right starting from $1. But even if the group doesn't get matched, it will exist (but contain empty value).

# fullpath variable will contain full request path
SetEnvIf Host (.*) and Request_URI (.*) and Query_String (.*) fullpath=http://$1$2?$3