Sun Java System Web Server 7.0 Update 7 Administrator's Configuration File Reference

Appendix A Using Variables, Expressions, and String Interpolation

This appendix describes variables, expressions, and string interpolation, and has the following sections:

Variables

The Web Server includes a set of variables predefined by the server, as well as the capability for you to define custom variables. This section includes the following sections:

Predefined Variables

Predefined variables are implicitly defined by the server. The following table lists the predefined variables and their descriptions:

Table A–1 Predefined Variables

Variable 

Description 

$n

Regular expression backreference (value of the nth capturing subpattern, n = 1...9), for example, $1.

Regular expression backreferences are only available within the body of If and ElseIf containers, and only if the container expressions includes one or more regular expressions. For more information on If and ElseIf, see If, ElseIf, and Else.

$&

Value that matched a regular expression. 

Regular expression backreferences are only available within the body of If and ElseIf containers, and only if the container expressions includes one or more regular expressions. For more information on If and ElseIf, see If, ElseIf, and Else.

$auth_group

Authenticated user's group (alias for $vars{'auth-group'}).

$auth_type

Authentication method (alias for $vars{'auth-type'}).

$auth_user

Authenticated user name (alias for $vars{'auth-user'}).

$browser

Web browser version (alias for $headers{'user-agent'} if the client sent a User-Agent header or an empty string).

$chunked

Boolean variable that indicates whether request body was sent using chunked encoding. 

$code

Response status code. 

$cookie{'name'}

Value of the cookie name from request.

$dns

Alias for $client{'dns'}.

$env{'name'}

Value of the environment variable name (includes CGI/SHTML environment variables).

$headers{'name'}

Value of name from rq->headers, that is, value of the request header name where name is a lowercase string.

$id

Virtual server ID as specified by the name subelement of the virtual-server element in server.xml. For more information, see virtual-server.

$internal

Boolean that indicates whether request was internally generated. 

$ip

Alias for $client{'ip'}.

$keep_alive

Boolean that indicates whether the connection will be kept open. 

$keysize

Alias for $client{'keysize'}.

$method

Request method (alias for $reqpb{'method'}).

$path

Requested path (either URI, partial path, or file system path depending on stage). 

The predefined variable path is the value of path from rq->vars. If path isn't set in rq->vars (for example, if NameTrans hasn't completed), path gets the value of ppath from rq->vars.

$path_info

Alias for $vars{'path-info'}.

$ppath

Alias for $vars{'ppath'}.

$protocol

Request protocol (alias for $reqpb{'protocol'}).

$query

Request query string (alias for $reqpb{'query'}).

$reason

Response reason phrase. 

$referer

Alias for $headers{'referer'}.

$reqpb{'name'}

Value of name from rq->reqpb.

$restarted

Boolean that indicates whether request has been restarted. 

$secret_keysize

Alias for $client{'secret-keysize'}.

$server_url

Prefix for self-referencing URLs. 

$time

Time the request was received as the number of seconds since 00:00:00 UTC, January 1, 2006. 

$time_day

Day of the month when the request was received. Value can be from 01 to 31. 

$time_hour

Hours since midnight when the request was received. Value can be from 00 to 23. 

$time_min

Minutes after the hour when the request was received. Value can be from 00 to 59. 

$time_mon

Month of the year when the request was received. Value can be from 01 to 12. 

$time_sec

Seconds after the minute when the request was received. Value can be from 00 to 61. 

$time_wday

Day of the week when the request was received. Value can be from 0 to 6, where 0 corresponds to Sunday. 

$time_year

Four-digit year when the request was received. 

$type

Alias for $srvhdrs{'content-type'}.

$uri

URI of the requested resource (alias for $reqpb{'uri'}).

$url

URL of the requested resource. 

$urlhost

Host name to which the client connected. 

$vars{'$headers{'name'}

Value of name from rq->vars.

$security

Boolean that indicates whether a secure transport was used. 

$senthdrs

Boolean that indicates whether response headers have been sent. 

$srvhdrs{'$headers{'name'}

Value of name from rq->srvhdrs, that is, value of response header name where name is a lowercase string.

Custom Variables

You can define custom variables in the server.xml file using the variables element. These variables can then be used in function parameters in obj.conf functions. You can also define variables at request time using the set-variables function in obj.conf.

For more information, see variable and set-variable.


Note –

Because predefined variables take precedence over custom variables, it is a best practice to use uppercase names for custom variables. Using uppercase avoids conflicts with the lowercase predefined variables, should the list of predefined variables be extended in the future.


Resolving Variables

    The server uses the following order when attempting to resolve a $variable:

  1. Predefined variables

  2. Variables defined at request time using set-variable in obj.conf

  3. Variables defined by the virtual-server element's variable subelement in server.xml

  4. Variables defined by the server element's variable subelement in server.xml

When you define a $variable at request time, it is stored as a name-value pair in the rq->vars pblock. These variables are given a higher precedence than server.xml variables so that server.xml variables can be overridden at request time.

Expressions

Expressions allow you to dynamically construct SAF parameters and to select which SAFs to execute on a request-by-request basis. Expressions are constructed from literals, variables, functions, and operators. Use expressions in If and ElseIf tags (see If, ElseIf, and Else), in log format strings (see Appendix C, Using the Custom Log File Format), and SAF parameters (see String Interpolation).

This section contains the following sections:

Expression Syntax

The expression syntax is similar to the syntax used in Perl. Expressions are constructed from literals, variables, functions, and operators.

The following example shows an expression used in an If tag:

<If not $internal
    and $uri =~ "^/private/(.*)$" 
    and $referer !~ "^https?://example.com/"> 
NameTrans fn="redirect" 
          url="http://example.com/denied.jsp?file=$1" 
</If> 

This example expression checks to see if a request meets certain criteria, for example if it is an internal request. If it does not meet the criteria, the server redirects the request to a request denied URL.

The expression contains the following components:

Expression Results as Booleans

In some circumstances, for example, after evaluating an If or ElseIf expression, the server must treat the result of an expression as a Boolean. The server uses the following rules when converting a numeric value to a Boolean:

The server uses the following rules when converting a string to a Boolean:

Expression Literals

Expression literals are divided into string and numeric literals.

String Literals

A string literal is bracketed by either single quotes (') or double quotes ("). When single quotes bracket a string literal, the value of the literal is the value within the quotes. When double quotes are used, any references to variables or expressions within the quotes are interpolated. For more information, see String Interpolation.

The following expression examples show the use of single and double quotes.

# This expression evaluates to true
('foo' eq "foo")

# This expression evaluates to false
('foo' eq "bar")

# This expression evaluates to true
('foo' eq "f$(lc('O'))o")

# This expression may evaluate to true or false,
# depending on the value of the variable $foo
('$foo' eq "$foo")

To include an uninterpolated $ character in a double quote string, use the $$ or \$ escape sequences.

When a double quote character appears within a literal bracketed by double quotes, it must be prefixed with a backslash. When a single backslash (\) character appears within a literal bracketed by double quotes, it must be prefixed with a backslash. When a single quote character appears within a literal bracketed by single quotes, it must be prefixed with a backslash.

The following examples show valid and invalid literals:

# The following are examples of valid literals
'this string literal is bracketed by single quotes'
"this string literal is bracketed by double quotes"
"the backslash, \\, escapes characters in double quote string literals"
'it\'s easy to use strings literals'

# The following are examples of invalid literals
'it's important to escape quote characters'
"any \ characters in double quote string literals must be escaped"

Numeric Literals

A numeric literal can consist of decimal digits and an optional decimal point, a leading zero followed by octal digits, or a leading 0x prefix followed by hexadecimal digits. Hexadecimal and octal numbers are automatically converted to decimal form.

The following examples show expressions that use numeric literals:

# The following expressions evaluate to true
(1 < 2)
(0x10 == "16")
(1 == 1.00)

# The following expressions evaluate to false
(1 > 2)
("0x10" == 16)
(1 != 1.00)

Expression Variables

Any $variable can be used as a variable in an expression. To mirror the Client tag syntax, the $ prefix is optional for predefined variable names in expressions. For example, the following three portions of obj.conf are all semantically equivalent:

<If $uri = "*.html">
...
</If>

<If uri = "*.html">
...
</If>

<Client uri = "*.html">
...
</Client>

Any variable names you define must use the $ prefix. For example, the following expression is invalid even if somecustomvariable is defined in a server.xml variable element:

<If somecustomvariable = "foo">
...
</If>

To make this expression valid, add the dollar sign prefix:

<If $somecustomvariable = "foo">
...
</If>

Expression Operators

The following table lists the operators that are used in expressions.

Table A–2 List of Expression Operators

Operator Symbol 

Operator Name 

!

C-style logical not 

=

Wildcard pattern match 

=~

Regular expression match 

!~

Regular expression mismatch 

+

Addition or unary plus 

-

Subtraction or unary minus 

.

String concatenation 

defined

Value is defined 

-d

Directory exists 

-e

File or directory exists  

-f

File exists 

-l

Symbolic link exists 

-r

File is readable 

-s

File size 

-U

URI maps to accessible file or directory 

<

Numeric less than 

<=

Numeric less than or equal to  

>

Numeric greater than 

>=

Numeric greater than or equal to 

lt

String less than 

le

String less than or equal to 

gt

String greater than 

ge

String greater than or equal to 

==

Numeric equal 

!=

Numeric not equal  

eq

String equal 

ne

String not equal 

^

C-style exclusive or 

&&

C-style logical and 

||

C-style logical or 

not

Logical not 

and

Logical and 

or

Logical or 

xor

Logical exclusive or 

The following table lists the precedence of operators within expressions from highest to lowest precedence.

Table A–3 Operator Precedence

Symbol 

Operands 

Associativity 

Description 

( ), [ ]

Left to right 

Parentheses 

!, unary +, unary -

Right to left 

Sign operators 

=, =~, !~

Non-associative 

Pattern matching operators 

+, -, .

Non-associative 

Additive operators 

defined, -d, -f, -l, -r, -s, -U

Right to left 

Named operators 

<, lt, <=, le, >, gt, >=, ge

Non-associative 

Relational operators 

==, eq, !=, ne

Non-associative 

Equality operators 

^

Left to right 

C-style exclusive or operator 

&&

Left to right 

C-style logical and operator 

||

Left to right 

C-style logical or operator 

not

Right to left 

Logical not operator 

and

Left to right 

Logical and operator 

or, xor

Left to right 

Logical or operators 

The numeric operators (<, <=, >, >=, ==, and !=) are intended to operate on numbers and not strings. To facilitate comparing numbers, dates, and timestamps, the numeric operators ignore any white space, colons, slashes, and commas in their arguments. Dashes after the first digit are also ignored.


Note –

It is generally incorrect to use the numeric operators on non-numeric values.


For example, the following expression evaluates to true:

# The following expression evaluates to true because both
# "foo" and "bar" are numerically equivalent to 0
("foo" == "bar")

Expression Functions

Expression functions manipulate data for use in expressions. Expression functions are different from SAFs. While SAFs perform the actual work associated with an HTTP request, expression functions are used to select which SAFs run and what parameters to pass to the SAFs.

Some expression functions require one or more arguments. An expression function's argument list is bracketed by parentheses (()) and the individual arguments are separated by commas (,).

The individual expression functions are listed in the following sections:

atime

The atime function returns the time of the last access for the specified file or directory.

Syntax

atime(path)

Arguments

The following table describes the argument for the expression function.

Table A–4 atime Argument

Argument 

Description 

path

The absolute path to the directory or file name for which you are requesting the last access 

See Also

choose

The choose function parses pipe-separated values from values and returns one at random.

Syntax

choose(values)

Arguments

The following table describes the argument for the expression function.

Table A–5 choose Argument

Argument 

Description 

values

The list of values to choose from, separated by the pipe character (|)

Example

The following obj.conf code demonstrates the use of choose to randomly select one of three images:

NameTrans fn="rewrite"
          from="/images/random"
          path="/images/$(choose('iwsvi.jpg|0061.jpg|webservervii.jpg'))"

ctime

The ctime function returns the time of the last status change for the specified file or directory.

Syntax

ctime(path)

Arguments

The following table describes the argument for the expression function.

Table A–6 ctime Argument

Argument 

Description 

path

The absolute path to the directory or file name for which you are requesting the last status change 

See Also

escape

The escape function encodes the URI using util_uri_escape, converting special octets to their %-encoded equivalents, and returns the result.

Syntax

escape(uri)

Arguments

The following table describes the argument for the expression function.

Table A–7 escape Argument

Argument 

Description 

uri

The URI that the expression function converts 

See Also

unescape

external

The external function passes a value to an external rewriting program and returns the result.

Each invocation of external results in a single newline-terminated line being written to the external rewriting program's stdin. For each line of input, the program must produce a single line of output. When developing an external rewriting program, it is important to avoid buffering stdout. In Perl, for example, $| = 1; should be used to disable buffering. Because the server expects the external rewriting program to produce one line of output for each line of input, the server can hang if the external rewriting program buffers its output.

Syntax

external(program, value)

Arguments

The expression function has the following arguments.

Table A–8 external Arguments

Argument 

Description 

program

The program argument is the file name of an external rewriting program. Because program is executed using the operating system's default shell (/bin/sh on Unix/Linux) or the command interpreter (CMD.EXE on Windows), program should be an absolute path or the name of a program in the operating system's PATH. The server starts the external rewriting program on demand. A given server process never executes more than one instance of the program at a time.


Note –

The server may start multiple instances of a given external rewriting program when the server is running in multiprocess mode.


value

The value passed to the rewrite program. 

Example

The following is an example of an external rewriting program rewrite.pl, used to change the prefix /home/ to /u/:

#!/usr/bin/perl
$| = 1;
while (<STDIN>) {
    s|^/home/|/u/|;
    print $_;
}

In this example, the external expression function used to invoke rewrite.pl is as follows:

NameTrans fn="rewrite" path="$(external('rewrite.pl', $path))"

httpdate

The httpdate function returns an RFC 1123 date/time stamp for use in HTTP header fields such as Expires.

Syntax

httpdate(time)

Arguments

The following table describes the argument for the expression function.

Table A–9 httpdate Argument

Argument 

Description 

time

The time value 

Example

The following obj.conf code could be used to set an Expires header that indicates a response is not cached for more than one day:

ObjectType fn="set-variable"
           insert-srvhdrs="$(httpdate($time + 86400))"

lc

The lc function converts all the US ASCII characters in the string to lowercase and returns the result.

syntax

lc(string)

Arguments

The following table describes the argument for the expression function.

Table A–10 lc Argument

Argument 

Description 

string

The string the expression function converts to lowercase 

Example

The following obj.conf code can be used to redirect clients who erroneously used uppercase characters in the request URI to the equivalent lowercase URI:

<If code == 404 and not -e path and -e lc(path)>
Error fn="redirect" uri="$(lc($uri))"
</If>

See Also

uc

length

The length function returns the length of its argument, that is, a number representing the length of the string.

Syntax

length(string)

Arguments

The following table describes the argument for the expression function.

Table A–11 length Argument

Argument 

Description 

string

The string for which the expression function computes the length. 

Example

The following obj.conf code can be used to send a 404 Not found error to clients that request URIs longer than 255 bytes:

<If length($uri) > 255)>
PathCheck fn="deny-existence"
</If>

lookup

The lookup function inspects a text file for a name-value pair with name name and returns the corresponding value. The name-value pairs in the file are separated by white space.

If the file does not contain a name-value pair with the specified name, this function returns the value of defaultvalue, if specified, or returns an empty string.

Syntax

lookup(filename, name, defaultvalue)

Arguments

The expression function has the following arguments:

Table A–12 lookup Arguments

Argument 

Description 

filename

filename is the name of a text file that contains one name-value pair per line. filename can be an absolute path or a path relative to the server's config directory. Names and values are separated by white space. Lines beginning with # are ignored.

name

The name of the name-value pair for which the function looks in the text file. 

defaultvalue

The value returned by the function if filename exists but does not contain a name-value pair with a name matching the value of name. If defaultvalue is not specified, it defaults to an empty string.

Example

The following example shows a text file called urimap.conf that could be used with the lookup function to map shortcut URIs to URIs:

# This file contains URI mappings for Web Server.
# Lines beginning with # are treated as comments.
# All other lines consist of a shortcut URI, whitespace, and canonical URI.
/webserver /software/products/web_srvr/home_web_srvr.html
/solaris   /software/solaris/
/java      /software/java/

Using the sample text file above, you could use the following lookup expression to implement shortcut URIs for commonly accessed resources:

<If lookup('urimap.conf', uri)>
NameTrans fn="redirect" url="$(lookup('urimap.conf', uri))"
</If>

mtime

The mtime function returns the time of the last data modification for the specified file or directory.

Syntax

mtime(path)

Arguments

The following table describes the argument for the expression function.

Table A–13 mtime Argument

Argument 

Description 

path

The absolute path to the directory or file name for which you are requesting the last data modification 

See Also

owner

The owner function returns the owner of a file.

Syntax

owner(path)

Arguments

The following table describes the argument for the expression function.

Table A–14 owner Argument

Argument 

Description 

path

The absolute path to the directory or file name for which you are requesting the last data modification 

uc

The uc function converts all the US ASCII characters in string to uppercase and returns the result.

Syntax

uc(string)

Arguments

The following table describes the argument for the expression function.

Table A–15 uc Argument

Argument 

Description 

string

The string that the expression function converts to uppercase 

See Also

lc

unescape

The unescape function decodes the URI using util_uri_unescape, converting %-encoded octets to their unencoded form, and returns the result.

Syntax

unescape(uri)

Arguments

The following table describes the argument for the expression function.

Table A–16 unescape Argument

Argument 

Description 

uri

The URI that the function converts 

See Also

escape

uuid

The uuid function returns a UUID as a string. No two calls to uuid return the same UUID. Because they are guaranteed to be unique, UUIDs are useful for constructing client-specific cookie values.

Syntax

uuid()

Regular Expressions

The If and ElseIf expressions may evaluate regular expressions using the =~ and !~ regular expression matching operators. These regular expressions use the Perl-compatible syntax implemented by Perl-compatible Regular Expressions (PCRE).

By default, regular expressions are case sensitive. The (?i) option flag can be added to the beginning of a regular expression to request case insensitivity. For example:

$uri =~ '^/[Ff][Ii][Ll][Ee][Nn][Aa][Mm][Ee]$'

$uri =~ '(?i)^/filename$'

When an If or ElseIf expression contains a regular expression, regular expression backreferences can appear within arguments in the container body. Regular expression backreferences are of the form $n where n is an integer between 1 and 9 corresponding to the capturing subpattern of the regular expression.

For example:

<If $path =~ '^(.*)(\.html|\.htm)$'>
NameTrans fn="rewrite" path="$1.shtml"
</If>

In the above example, two subpatterns are used in the If expression, so $1 and $2 can be used as backreferences. In the example, the value of the first capturing subpattern is used within a NameTrans fn="rewrite" parameter. The value of the second capturing subpattern is ignored.

An If or ElseIf expression can contain backreferences to earlier regular expressions in that same If or ElseIf expression.

For example:

<If "foo" =~ "(.*)" and $1 eq "foo">
# Any contained directives will be executed
# since $1 will evaluate to "foo"
...
</If>

The contents of the above If expression are executed, because the given If expression always evaluates to true.

However, If and Elseif expressions, and contained directives, can't contain backreferences to regular expressions in parent containers. For example, the following obj.conf entry is invalid:

<If $path =~ '(.*)\.css'>
<If $browser = "*MSIE*">
# This example is invalid as $1 is not defined
AuthTrans fn="rewrite" path="$1-msie.css"
</If>
</If>

You can use $& to obtain the value that last successfully matched a regular expression. Use the following obj.conf entry to redirect requests for HTML files to another server:

<If $path =~ '\.html$' or $path =~ '\.htm$' >
NameTrans fn="redirect" url="http://docs.example.com$&"
</If>

String Interpolation

Strings that contain references to variables or expressions are called interpolated strings. When you use interpolated strings, the embedded expressions and variables are evaluated and the result is inserted into the string. The act of inserting data into a string is called string interpolation.

Use interpolated strings in expressions, log formats, and obj.conf parameters. In expressions, only string literals bracketed by double quotes are interpolated. For more information, see Expression Literals.

Using Variables in Interpolated Strings

To include the value of a variable in a string, prefix the name of the variable with the dollar-sign ($). For example, the following format element in server.xml logs the client IP address, requested URI, and corresponding file system path for each HTTP request:

<access-log>
  <file>access</file>
  <format>$ip "$uri" $path</format>
</access-log>

In this example, $ip, $uri, and $path are predefined variables. For more information, see Variables.

For more information on access logs and log format, see Appendix C, Using the Custom Log File Format. For more information on the access-log element in server.xml, see access-log.

If the name of the variable is ambiguous, add curly braces, {}, to the name. For example, the following string contains a reference to the predefined $path variable:

"${path}html"

Without the curly braces, the string instead contains a reference to a hypothetical variable named pathhtml.

Using Expressions in Interpolated Strings

To include the result of an expression in a string, prefix the expression with $(and follow it with ). For example, the following two strings are identical after interpolation:

"$(2 + 2)"

"4"

When an interpolated string is used as an obj.conf parameter, the string is interpolated each time the corresponding instruction is executed. For example, the following lines could be used in obj.conf to redirect clients based on the requested URI and the contents of the file redirect.conf:

<Object ppath="/redirect/*">
NameTrans fn="redirect" url="$(lookup('redirect.conf', $uri, '/'))"
</Object>

In this example, the expression lookup('redirect.conf', $uri, '/') is evaluated each time the NameTrans directive is invoked, and the result is passed to the redirect SAF in its url parameter. For more information on the redirect SAF, see redirect. For more information on the lookup expression function, see lookup.