© David Ashley 2020
D. AshleyFoundation Dynamic Web Pages with Pythonhttps://doi.org/10.1007/978-1-4842-6339-6_4

4. Using SSI and Python

David Ashley1 
(1)
Austin, TX, USA
 

The Server Side Includes (SSI) scripting language triggers further processing on your static web pages. The server parses an HTML page looking for SSI directives. It then processes those directives and creates a new page that in turn is passed back to the user. The modification directives that SSI supplies can do simple text replacement or can call programs to supply the text. The range of possibilities is endless for SSI, and you will see an example of each SSI directive in this chapter.

Getting Started

To use SSI directives in your HTML pages, you must configure SSI in the server configuration file. It is easy to perform this configuration, but it must be placed in the main portion of the config file. There are only two statements to add, as shown in Listing 4-1.
AddHandler server-parsed .shtml
Options +Includes
Listing 4-1

SSI Configuration Statements

After adding these statements, you will need to restart the HTTP server to activate them.

Note

You may also have to add Includes in Options Indexes FollowSymLinks to make this work with the default settings, as shown here:

<Directory "/var/www/html">
   Options Indexes Includes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

The shtml portion of the AddHandler statement specifies the file extension that will be used to tell the server which HTML files need to be parsed for SSI directives. Only files with this extension will be parsed for SSI directives.

If your website is running on a Unix or Linux operating system, there is an alternative available to using a special filename for HTML files that contain SSI directives. The HTTP server directive XBitHack allows you to set the owner execute bit on the file to indicate that the server should parse the file for SSI directives. If you choose to use this directive, then your server config file should contain the directives shown in Listing 4-2.
AddHandler server-parsed .shtml
Options +Includes
XBitHack on
Listing 4-2

SSI Configuration Statements with XBitHack Directive

When configured this way, the .shtml file extensions will be ignored, and only files with the owner execute bit set will be parsed for SSI directives.

There are additional statements that can be placed in the HTTP server configuration file that will alter the processing of the file by SSI, but we will look at those later in this chapter.

../images/498589_1_En_4_Chapter/498589_1_En_4_Figa_HTML.jpg Important

SSI directives placed in the output of CGI programs will not be processed. This because no filename is associated with the CGI output, so the server has no way to know whether it needs to be parsed.

SSI directives are really no more than specially formatted HTML comments. This to make them stand out from normal comments and be easily parsed by the server. The general format of an SSI directive follows:
<!--#element attribute="value" attribute="value" ... -->

The pound sign (#) is what identifies this comment as an SSI directive. If a directive accepts attributes, then the attributes should follow the directive name. There are eight SSI directives plus some miscellaneous ones, and the following sections describe each one.

The config SSI Directive

The config directive controls some aspects of parsing. Three attributes are available, all of which have default values. This directive overrides the default or any previous modification to the attribute. It can appear more than once in your HTML file or not at all. The syntax is as follows:
<!--#config errmsg="Your error msg" sizefmt="The format for display od file sizes"
            timefmt="Format for displaying time values" -->
The following are the definitions for each attribute:

errmg

This is the message sent back to the client when an error occurs during document parsing.

sizefmt

This is the value to use when displaying the size of a file. Valid values are bytes or abbrev for a size in kilobytes or megabytes as appropriate.

timefmt

This value is the same as passed to the C function strftime() library routine.

Listing 4-3 shows a simple HTML page that displays each attribute of the config directive. We deliberately removed all the framing from the example to make it as simple as possible. Obviously, this will work on a more complicated HTML page as well.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-1</title>
    <meta http-equiv="Content-Type" content="text/html;
     charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-1 - errmsg SSI Directive</h1>
    <p>The following is an example of the <i>config errmsg</i>
       SSI directive. The error message should be
       "This is an example error!".</p>
    <!--#config errmsg="This is an example error!"-->
    <!--#config xerrmsg="This is an example error!"-->
    <br/>
    <p>The following is an example of the <i>config sizefmt</i>
       SSI directive. The file size should be presented in either
       kilobytes or megabytes.</p>
    <!--#config sizefmt="abbrev"-->
    <!--#fsize file="./example4-1.html"-->
    <br/>
    <p>The following is an example of the <i>config timefmt</i>
       SSI directive. The file time should be presented as
       "%A %Y-%m-%d %H:%M:%S".</p>
    <!--#config timefmt="%A %Y-%m-%d %H:%M:%S"-->
    <!--#flastmod file="./example4-1.html"-->
</body>
</html>
Listing 4-3

An Example HTML Page Using the SSI errmsg Directive

The code in Listing 4-3 will display in the browser as shown in Figure 4-1.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig1_HTML.jpg
Figure 4-1

Output from Listing 4-3

As you can see, this SSI directive can save you a lot of work updating content in your HTML pages. When the file is modified, the file size and update timestamp can also be updated automatically.

The error message produced can also be modified throughout the document to make it specific to errors in different parts of the document.

The echo SSI Directive

The echo SSI directive prints out the value of an assigned environment variable. A limited number of environment variables can be printed in the document. There is only one attribute available for this directive, and it is documented here:

var

This is the name of the environment to be printed. Only the following environment variables may be specified: DATE_GMT, DATE_LOCAL, DOCUMENT_NAME, DOCUMENT_URI, and LAST_MODIFIED.

Listing 4-4 shows an example of each possibility for the echo directive.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-2</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-2 - errmsg SSI Directive</h1>
    <p>The following is an example of the <i>config echo</i> SSI directive.</p>
    <p>DATE_GMT = <!--#echo var="DATE_GMT"--></p>
    <p>DATE_LOCAL = <!--#echo var="DATE_LOCAL"--></p>
    <p>DOCUMENT_NAME = <!--#echo var="DOCUMENT_NAME"--></p>
    <p>DOCUMENT_URI = <!--#echo var="DOCUMENT_URI"--></p>
    <p>LAST_MODIFIED = <!--#echo var="LAST_MODIFIED"--></p>
</body>
</html>
Listing 4-4

An Example of the SSI echo Directive

The code in Listing 4-4 will display in the browser as shown in Figure 4-2.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig2_HTML.jpg
Figure 4-2

Output from Listing 4-4

Although the number of environment variables is restricted, the echo directive is still a convenient directive to use when needed. It can still save time and reduce the number of times an HTML file is updated.

The exec SSI Directive

The exec SSI directive executes either a shell command or a CGI script. A prudent webmaster will put the option IncludesNOEXEC in the server config file to disable this SSI directive. But if available, it allows the output from a shell command, program, or CGI script to be included at that point in the HTML file.

Two attributes are available for the exec directive, as documented here:

cgi

This is a %-encoded URL relative path to the CGI script. If the path does not include a leading slash, it is taken to be relative to the current document. The document is invoked as a CGI script even if the server does not recognize it as a CGI program. All the rules for a directory containing a CGI script must be observed. If suexec is turned on, it will be enforced. The QUERY_STRING and PATH_INFO environment variables passed to the original document will be passed in turn to the specified CGI script as well as the include variables. Note that the include virtual SSI directive should be used in preference to the exec directive if possible.

cmd

The server prepends the /bin/sh string to the front of this attribute and then attempts to execute it. The include variables are available to the command, and its output of the program will be included in the HTML file at that point.

../images/498589_1_En_4_Chapter/498589_1_En_4_Figb_HTML.jpg Important

The documentation for the SSI exec directive is not exactly clear. You should be aware that whatever HTML appears in the original HTML request will be thrown away on successful execution of the code being called. This is true for both the cgi and cmd attributes.

Listing 4-5 shows an example of both attributes.
<!DOCTYPE HTML>
<html>
<body id="body">
    <!--#exec cgi="/cgi-bin/example4-3a.py"-->
</body>
</html>
<!DOCTYPE HTML>
<html>
<body id="body">
    <!--#exec cmd="/cgi-bin/example4-3b.sh"-->
</body>
</html>
Listing 4-5

Example Code for the SSI Directives exec cgi and exec cmd

Note that the only thing the documents in Listing 4-5 do is call the SSI directives exec cgi and exec cmd. These commands will in turn call a script to output the actual HTML for the request.

Listing 4-6 shows the code for both commands.
#!/usr/bin/python3
from time import gmtime, strftime
print('Content-type:text/html ')
print('<!DOCTYPE html>')
print('<html>')
print('<body>')
print('<p>This is output from the example4-3a.py cgi script. ')
print('The current date is ' + strftime("%A %c", gmtime()) + '.</p>')
print('</body>')
print('</html>')
#!/usr/bin/sh
echo "Content-type:text/html"
echo ""
echo "<!DOCTYPE html>"
echo "<head>"
echo "   <meta http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" />"
echo "</head>"
echo "<html>"
echo "<body>"
echo "<p>This is output from a shell script. "
echo "The current date is $(date).</p>"
echo "</body>"
echo "</html>"
Listing 4-6

The Scripts Called by the SSI Directives in Listing 4-5

The code in Listing 4-6 is responsible for all the output from each request. The Python script is called for the first request, and the shell script is called from the second request.

Figure 4-3 shows the output from each request.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig3_HTML.jpg
Figure 4-3

Output from the two previous code listings

Figure 4-3 shows the output in the browser. You cannot quite see it, but the request field indicates that this output came from the original HTML request and not the scripts that were called from the HTML. This hides the fact that a CGI or CMD SSI directive was called to actually create the output dynamically. Even if you look at the source for the document, you cannot tell it did not come from the HTML request. This could be useful in hiding just how the output HTML was created.

You should also note that the QUERY_STRING and CONTEXT_DOCUMENT_ROOT are the values passed to the original HTML request and remain unmodified when passed to the cgi and cmd attributes. There could be other environment variables that have original values as well. This can be useful when the directory where the HTML file resides is important to the request.

It is preferable to use the include SSI directive instead of the exec directive wherever possible as the potential of a security failure goes up when this exec directive is used.

The fsize SSI Directive

This directive prints the size of the specified file. The output is dependent on the sizefmt attribute from the config SSI directive. There are two attributes (mutually exclusive) to specify the file, as described here:

file

This is a path/filename relative to the directory containing the current HTML file.

virtual

The %-encoded URL path relative to the DOCUMENT_ROOT from the server config file. If the specification does not begin with a slash (/), it means that it is relative to the current HTML document.

Listing 4-7 contains examples of both fsize attributes. They both will appear in the HTML page’s output.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-4</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-4 - fsize SSI Directive</h1>
    <p>The following is an example of the <i>fsize file=</i> SSI directive. The file size should be presented in either
    kilobytes or megabytes.</p>
    <!--#config sizefmt="abbrev"-->
    <!--#fsize file="./example4-4.html"-->
    <p>The following is an example of the <i>fsize virtual=</i> SSI directive. The file size should be presented in either
    kilobytes or megabytes.</p>
    <!--#fsize virtual="./example4-4.html"-->
</body>
</html>
Listing 4-7

The HTML Document Containing the fsize Directive

Figure 4-4 shows the browser output after requesting this document.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig4_HTML.jpg
Figure 4-4

Output from Listing 4-7

Output from the fsize directive appears inline within the output HTML page. The example in Figure 4-4 has paragraph tags surrounding the size so that it stands out in the example. Also, the size of the original HTML file is small, less than a kilobyte in size, which means there is not a qualifier for the size.

The flastmod SSI Directive

This directive prints the last modification timestamp of the specified file. The output is dependent on the timefmt attribute from the config SSI directive. There are two attributes (mutually exclusive) to specify the file, as described here:

file

This is a path/filename relative to the directory containing the current HTML file.

virtual

This is the %-encoded URL path relative to the DOCUMENT_ROOT from the server config file. If the specification does not begin with a slash (/), it means that it is relative to the current HTML document.

Listing 4-8 contains examples of both flastmod attributes. They both will appear in the HTML page’s output.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-4</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-4 - fsize SSI Directive</h1>
    <p>The following is an example of the <i>fsize file=</i> SSI directive. The file
       size should be presented in either kilobytes or megabytes.</p>
    <!--#config sizefmt="abbrev"-->
    <!--#fsize file="./example4-4.html"-->
    <p>The following is an example of the <i>fsize virtual=</i> SSI directive. The file size should be presented in either
    kilobytes or megabytes.</p>
    <!--#flastmod virtual="./example4-4.html"-->
</body>
</html>
Listing 4-8

The HTML Document Containing the flastmod Directive

Figure 4-5 shows the browser output after requesting this document.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig5_HTML.jpg
Figure 4-5

Output from Listing 4-8

Output from the flastmod directive appears inline within the output HTML page. The example in Figure 4-5 has paragraph tags surrounding the timestamp so that it stands out in the example. The timestamp is shown using the default format.

The include SSI Directive

This directive prints the contents of the file pointed to by the attribute. There are two attributes (mutually exclusive) to specify the file, described here:

file

This is a path/filename relative to the directory containing the current HTML file.

virtual

The %-encoded URL path relative to the DOCUMENT_ROOT from the server config file. If the specification does not begin with a slash (/), it means that it is relative to the current HTML document.

Listing 4-9 contains examples of both include attributes. They both will appear in the HTML page’s output.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-6</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-6 - include SSI Directive</h1>
    <p>The following is an example of the <i>include file=</i> SSI directive.</p>
    <!--#include file="./example4-6a.html"-->
    <p>The following is an example of the <i>include virtual=</i> SSI directive.</p>
    <!--#include virtual="/html_lib/example4-6b.html"-->
</body>
</html>
Listing 4-9

The HTML Document Containing the flastmod Directive

Figure 4-6 shows the browser output after requesting this document.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig6_HTML.jpg
Figure 4-6

Output from Listing 4-8

Output from the include directive appears inline within the output HTML page. You should ensure that the included content is a real HTML fragment and not an entire HTML page.

Please note it is not possible to call a script using this directive. Also, the included file may not contain other SSI directives as they will be ignored.

Additional SSI Directives

We will be introducing several SSI directives and concepts in this section because they are all closely related. This will include the set directive, additional variables that can be used in your SSI HTML pages, and conditional directives for selecting sets of phrases to be included in your document.

You should note that all the directives and variables described in this section are available in Apache version 2.4 and newer. They may not be available in your HTTP server.

The SSI set Directive

The set directive is used to set the value of variables. These variables are then available to the conditional directives we will describe later. The following shows an example of this directive:
<!--#set var="last_name" value="Ashley"-->

The two attributes var and value describe the name of the variable and its assigned value, respectively. In addition, there are two more attributes that are used only occasionally. They are decoding and encoding and are used for encoding and decoding the value passed to the variable name. There are several values you can pass in these attributes depending on the encoding you want to translate to/from the value attribute. You should see the Apache documentation before attempting to use them.

In addition to setting a literal string to the value, you can also assign some additional variable, which we will describe next. An example of this is shown here:
<!--#set var="modified_date" value="$LAST_MODIFIED"-->
Note the dollar sign ($) at the beginning of the variable name. This indicates the variable already exists and the value of the variable should be used. If you need to put a literal dollar sign at the start of your value string, you can escape the dollar sign with the backslash character, as shown here:
<!--#set var="amount" value="$150.00"-->
Finally, if you want to put a variable in the middle of a string, you should surround the variable name with curly brackets, as shown here:
<!--#set var="doc_name" value=" This document is named ${DOCUMENT_NAME}."-->

One last thing of note is to not use uppercase for your variable names. Apache reserves the right to add new variables to the current list, and those names will be uppercase names.

The current list of available variable names is as follows:

DATE_GMT

This is the server’s current timestamp in GMT format.

DATE_LOCAL

This is the server’s current timestamp in the server’s local format.

DOCUMENT_ARGS

This is the same as the CGI variable QUERY_STRING. If no arguments were passed, this will be the empty string.

DOCUMENT_NAME

This is the filename of the current HTML file.

DOCUMENT_PATH_INFO

This is the same the CGI PATH_INFO variable.

DOCUMENT_URO

This is the main HTML DOCUMENT_URI. In the cases of nested includes, this is not the URI of the nested file.

LAST_MODIFIED

This is the last modified timestamp of the main HTML file.

QUERY_STRING_UNESCAPED

This is the unescaped value of the query string.

USER_NAME

This is the username of the owner of the main HTML document.

All of these variables are available to be used in the set directive as well as all the conditional directives.

Listing 4-10 shows examples of all of these variables.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-7</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-7 - Additional Available Variables</h1>
    <p>The following is an example of the <i>DATE_GMT</i> SSI variable.</p>
    "<!--#echo var="DATE_GMT"-->"
    <p>The following is an example of the <i>DATE_LOCAL</i> SSI variable.</p>
    "<!--#echo var="DATE_LOCAL"-->"
    <p>The following is an example of the <i>DOCUMENT_ARGS</i> SSI variable.</p>
    "<!--#echo var="DOCUMENT_ARGS"-->"
    <p>The following is an example of the <i>DOCUMENT_NAME</i> SSI variable.</p>
    "<!--#echo var="DOCUMENT_NAME"-->"
    <p>The following is an example of the <i>DOCUMENT_PATH_INFO</i> SSI variable.</p>
    "<!--#echo var="DOCUMENT_PATH_INFO"-->"
    <p>The following is an example of the <i>DOCUMENT_URI</i> SSI variable.</p>
    "<!--#echo var="DOCUMENT_URI"-->"
    <p>The following is an example of the <i>LAST_MOFIFIED</i> SSI variable.</p>
    "<!--#echo var="LAST_MODIFIED"-->"
    <p>The following is an example of the <i>QUERY_STRING_UNESCAPED</i> SSI variable.</p>
    "<!--#echo var="QUERY_STRING_UNESCAPED"-->"
    <p>The following is an example of the <i>USER_NAME</i> SSI variable.</p>
    "<!--#echo var="USER_NAME"-->"
    <br/><p>Note: In the examples above the surrounding quotation marks are NOT a part of the variable.</p>
</body>
</html>
Listing 4-10

An HTML Example Showing How to Use the Available Variables

Figure 4-7 shows the output from running this page.
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig7_HTML.jpg
Figure 4-7

The output from Listing 4-10

The SSI Conditional Directives

The SSI conditional directives allow the user to specify HTML text to be included under certain conditions. The directives are if, elif, else, and endif. These directives operate in almost the same way as the C/C++ directives with the same names. The if directive specifies a condition, and if it is true, the text following it is included in the document. The elif directive specifies a different condition that is evaluated if the previous if or elif condition is false. The else condition includes the text that follows it if all previous conditions are false. The endif directive ends all conditional text.

../images/498589_1_En_4_Chapter/498589_1_En_4_Figc_HTML.jpg Warning

Do not mix the conditional directives with the previously documented set directive. The conditional directives are all evaluated early in the parsing phase of the HTML. The set directive (as well as all other SSI directives) is evaluated in a later phase after all the conditional directives have already been evaluated. Thus, the conditional directives have no access to the variables produced by the set directive.

Listing 4-11 shows how this works.
<!DOCTYPE HTML>
<html>
<head>
    <title>Example4-8</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body id="body">
    <h1>Example4-8 - Conditional Directives</h1>
    <p>The following is an example of the SSI conditional
       directives.</p>
    <!--#if expr="%{QUERY_STRING} =~ /^name=([a-zA-Z]+)/"-->
        <!--#if expr="$1 == 'David'"-->
            <p>The Name is correct.</p>
        <!--#else -->
            <p>The Name is NOT correct.</p>
        <!--#endif -->
    <!--#else -->
        <p>The Admin is missing.</p>
    <!--#endif -->
</body>
</html>
Listing 4-11

A Sample HTMP Page Using the Conditional Directives

Figure 4-8 shows one possible output (depending on the calling argument).
../images/498589_1_En_4_Chapter/498589_1_En_4_Fig8_HTML.jpg
Figure 4-8

One possible output from Listing 4-11

The URL to run the script shown in Figure 4-8 is as follows:
http://www.holmes4.com/book/example4-8.html?name=David

The previous command is the correct way to obtain a positive result from the script. Any other name or not providing one at all will give a negative result.

The syntax of the conditional directive is simple and matches the other directives we have examined so far. There is only a single attribute, and it is used on the if and elif conditional directives. The expr attribute specifies the conditional expression to be evaluated. The syntax of this condition will be explored a little later. If the condition is true, then the text following the directive will be included. The text can include other conditional directives or and of the SSI directives. Text is included until either an elif, else, or endif SSI directive is found. If the expression is false, all the text is skipped until the next conditional directive is found.

If we examine the condition on the if directive, we see that something called the QUERY_STRING is being examined for something on the right side of the expression. The QUERY_STRING is the same as for the CGI scripts. This is surrounded by %{...} to mark it as a known variable. We will list all the known variables for conditional expressions a little later. The right side of the expression is a regular expression. This expression uses the same syntax as regular expressions in Perl 5.0. The middle operator specifies how the variables on each side are to be evaluated. We will examine all the possible operators a little later.

Table 4-1 describes all the available variables for use by the conditional directives. These are the only variables that can be used by the conditional directives.

The tables that follow are all taken from sources on the Web, and any incorrect information is my mistake.
Table 4-1

SSI Conditional Directive Variables

Name

Description

HTTP_ACCEPT

Named HTTP request header variable.

HTTP_COOKIE

Named HTTP request header variable.

HTTP_FORWARDED

Named HTTP request header variable.

HTTP_HOST

Named HTTP request header variable.

HTTP_PROXY_CONNECTION

Named HTTP request header variable.

HTTP_REFERER

Named HTTP request header variable.

HTTP_USER_AGENT

Named HTTP request header variable.

REQUEST_METHOD

The HTTP method of the incoming request (e.g., GET).

REQUEST_SCHEME

The scheme part of the request’s URI.

REQUEST_URI

The path part of the request’s URI.

DOCUMENT_URI

Same as REQUEST_URI.

REQUEST_FILENAME

The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI.

SCRIPT_FILENAME

Same as REQUEST_FILENAME.

LAST_MODIFIED

The date and time of last modification of the file in the format 20101231235959, if this has already been determined by the server at the time LAST_MODIFIED is referenced.

SCRIPT_USER

The username of the owner of the script.

SCRIPT_GROUP

The group name of the group of the script.

PATH_INFO

The trailing path name information.

QUERY_STRING

The query string of the current request.

IS_SUBREQ

"true" if the current request is a subrequest, "false" otherwise.

THE_REQUEST

The complete request line (e.g., "GET /index.html HTTP/1.1").

REMOTE_ADDR

The IP address of the remote host.

REMOTE_PORT

The port of the remote host (2.4.26 and later).

REMOTE_HOST

The hostname of the remote host.

REMOTE_USER

The name of the authenticated user, if any (not available during <If>).

REMOTE_IDENT

The username set by mod_ident.

SERVER_NAME

The ServerName of the current vhost.

SERVER_PORT

The server port of the current vhost; see ServerName.

SERVER_ADMIN

The ServerAdmin of the current vhost.

SERVER_PROTOCOL

The protocol used by the request.

DOCUMENT_ROOT

The DocumentRoot of the current vhost.

AUTH_TYPE

The configured AuthType (e.g., "basic").

CONTENT_TYPE

The content type of the response (not available during <If>).

HANDLER

The name of the handler creating the response.

HTTP2

"on" if the request uses http/2, "off" otherwise.

HTTPS

"on" if the request uses https, "off" otherwise.

IPV6

"on" if the connection uses IPv6, "off" otherwise.

REQUEST_STATUS

The HTTP error status of the request (not available during <If>).

REQUEST_LOG_ID

The error log ID of the request (see ErrorLogFormat).

CONN_LOG_ID

The error log ID of the connection (see ErrorLogFormat).

CONN_REMOTE_ADDR

The peer IP address of the connection (see the mod_remoteip module).

CONTEXT_PREFIX

Tells you how the server used an Alias directive (or a similar feature, like mod_userdir) to translate the URL path to the file system path.

CONTEXT_DOCUMENT_ROOT

Tells you how the server used an Alias directive (or a similar feature, like mod_userdir) to translate the URL path to the file system path.

TIME_YEAR

The current year (e.g., 2010).

TIME_MON

The current month (01, ..., 12).

TIME_DAY

The current day of the month (01, ...).

TIME_HOUR

The hour part of the current time (00, ..., 23).

TIME_MIN

The minute part of the current time.

TIME_SEC

The second part of the current time.

TIME_WDAY

The day of the week (starting with 0 for Sunday).

TIME

The date and time in the format 20101231235959.

SERVER_SOFTWARE

The server version string.

API_VERSION

The date of the API version (module magic number).

The variables listed in Table 4-1 must always be specified in uppercase. The SSI processor is case sensitive, so keep that in mind as you write your HTML.

In addition to the variables listed in Table 4-1, you may also include quoted text as a constant. Constants can be surrounded with either single (') or double (") quotes.

Table 4-2 lists all the binary operators that may be used in conditional directives.
Table 4-2

Conditional Directive Binary Operators

Name

Alternative

Description

==

=

String equality

!=

 

String inequality

<

 

String less than

<=

 

String less than or equal

>

 

String greater than

>=

 

String greater than or equal

=~

 

String matches the regular expression

!~

 

String does not match the regular expression

-eq

eq

Integer equality

-ne

ne

Integer inequality

-lt

lt

Integer less than

-le

le

Integer less than or equal

-gt

gt

Integer greater than

-ge

ge

Integer greater than or equal

-ipmatch

 

IP address matches address/netmask

-strmatch

 

Left string matches pattern given by right string (containing wildcards *, ?, [])

-strcmatch

 

Same as -strmatch, but case insensitive

-fnmatch

 

Same as -strmatch, but slashes are not matched by wildcards

Table 4-3 lists all the unary operators used in conditional directives.
Table 4-3

Conditional Directive Unary Operators

Name

Description

-d

The argument is treated as a filename. True if file exists and is a directory.

-e

The argument is treated as a filename. True if the file (or dir or special) exists.

-f

The argument is treated as a filename. True if the file exists and is a regular file.

-s

The argument is treated as a filename. True if the file exists and is a regular file.

-L

The argument is treated as a filename. True if the file exists and is a symlink.

-h

The argument is treated as a filename. True if the exists and is a symlink (same as -L).

-F

True if string is a valid file, accessible via all the server’s currently configured access controls for that path. This uses an internal subrequest to do the check, so use it with care; it can impact your server’s performance.

-U

True if string is a valid URL, accessible via all the server’s currently configured access controls for that path. This uses an internal subrequest to do the check, so use it with care; it can impact your server’s performance.

-A

Alias for -U.

-n

True if string is not empty.

-z

True if string is empty.

-T

False if string is empty, "0", "off", "false", or "no" (case insensitive). True otherwise.

-R

Same as "%{REMOTE_ADDR} -ipmatch . . .", but more efficient.

At this point, it should be noted that there are no OR or AND operators. This means that only simple comparisons can be made in an if directive. Multiple comparisons must be made by nesting if directives.

Table 4-4 lists all the functions available for use in comparisons.
Table 4-4

Conditional Directive Functions

Name

Description

Notes

req, http

Gets HTTP request header; header names may be added to the Vary header

 

req_novary

Same as req, but header names will not be added to the Vary header

 

resp

Gets HTTP response header (most response headers will not yet be set during <If>)

 

reqenv

Looks up request environment variable (as a shortcut, v can also be used to access variables)

Ordering

osenv

Looks up operating system environment variable

 

note

Looks up request note

Ordering

env

Returns first match of note, reqenv, osenv

Ordering

tolower

Converts string to lowercase

 

toupper

Converts string to uppercase

 

escape

Escapes special characters in %hex encoding

 

unescape

Unescapes %hex-encoded string, leaving encoded slashes alone; return empty string if %00 is found

 

base64

Encodes the string using base64 encoding

 

unbase64

Decodes base64-encoded string; returns truncated string if 0x00 is found

 

md5

Hashes the string using MD5, then encodes the hash with hexadecimal encoding

 

sha1

Hashes the string using SHA1, then encodes the hash with hexadecimal encoding

 

file

Reads contents from a file (including line endings, when present)

Restricted

filemod

Returns last modification time of a file (or 0 if file does not exist or is not a regular file)

Restricted

filesize

Returns size of a file (or 0 if file does not exist or is not a regular file)

Restricted

The functions marked “Restricted” in the final column are not available in some modules like mod_include.

The functions marked “Ordering” in the final column require some consideration for the ordering of different components of the server. You should remember that the if directive is evaluated early in the response processing.

The following are some sample if directives to give you an idea of what is possible:
<!-- Compare the host name to example.com -->
<!--#if %{HTTP_HOST} == 'example.com' -->
<!-- Force text/plain if requesting a file with the query string contains 'forcetext' -->
<!--#if %{QUERY_STRING} =~ /forcetext/ -->
<!-- Check a HTTP header for a list of values -->
<!--#if %{HTTP:X-example-header} in { 'foo', 'bar', 'baz' } -->
<!-- Check an environment variable for a regular expression, negated. -->
<!--#if ! reqenv('REDIRECT_FOO') =~ /bar/ -->
<!-- Check against the client IP -->
<!--#if -R '192.168.1.0/24' -->
<!-- Function example in boolean context -->
<!--#if md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8' -->

Summary

Using SSI can be as easy or complicated as you want to make it. While it does not fit every situation, it is a useful tool for easing your web server maintenance. Used under the right circumstances, it can make everything easier.

This chapter has introduced all the concepts needed to make SSI work for you whatever your needs. Just remember that the main SSI directives are evaluated after the SSI conditional directives.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.202.187