eXtended Server Side Includes (XSSI)
[Language]
[Installation]
[Notes]
The eXtended Server Side Include
(XSSI)
extension to the
Apache HTTP Server
allows web developers to create dynamic documents without
having to write CGI scripts.
Some of the capabilities that I wanted include:
- Ability to change the document's html based on the web browser.
- Ability to maintain common headers and footers that contain
some document specific information.
- Ability to maintain copies of a web on multiple servers.
While this could all be done with CGI scripts, this suffers
several problems:
- Many web developers don't have access to CGI due to ISP restrictions.
- Embedding content inside a CGI program makes content maintenance
more difficult.
- CGI scripts often depend on having multiple copies of the same
information (for different browsers for example) which also makes
content maintenance much more difficult.
- Many web developers don't have programming expertise with Perl, tcl,
c, or other CGI languages.
XSSI is designed for the casual web developer. Someone developing a
departmental or personal home page on a intranet for example. It is
not intended to be a replacement for CGI. It is intended to simplify
casual web page development and maintenance.
XSSI is a drop-in replacement for the standard
Server Side Include feature of Apache.
It works by pre-processing the target file and sending the resulting
HTML document to the output stream. This is transmitted back to
the browser by the httpd server.
This guide covers
the complete XSSI language including both the original and the
new directives.
XSSI-1.0 works for Apache 1.0.3 - 1.0.5. XSSI-1.1 works for Apache
1.1 and above. XSSI has been tested on SunOS 4.1.3 and Linux 1.3.57.
Extended server side include directives are implemented as
as SGML comments in case the document should ever be handled
without being parsed. Each directive has the following format:
<!--#command tag1="value1" tag2="value2" -->
Variables
XSSI supports variables. You can use variables in the
tag value (for all tags except var=) of all directives:
<!--#command tag1="$variable" -->
<!--#command tag1="text${variable}more text" -->
The set directive is used to set the value of a
variable:
<!--#set var="variable_name" value="variable_value"-->
Some variables are set for the user. In addition to the
CGI variable set,
the following variables are made available:
DOCUMENT_NAME: The current filename.
DOCUMENT_URI: The virtual path to this document
(such as /docs/tutorials/foo.shtml).
QUERY_STRING_UNESCAPED: The unescaped version of any
search query the client sent, with all shell-special characters
escaped with \.
DATE_LOCAL: The current date, local time zone.
Subject to the timefmt parameter to the
config command.
DATE_GMT: Same as DATE_LOCAL but in Greenwich mean
time.
LAST_MODIFIED: The last modification date of the
current document. Subject to timefmt like the others.
The format of date and file size variables are set using the
config directive:
<!--#config errmsg="your error message" -->
<!--#config timefmt="strftime_time_format" -->
<!--#config sizefmt="bytes | abbrev" -->
errmsg controls what message is sent back to the
client if an error includes while parsing the document. When an error
occurs, it is logged in the server's error log.
timefmt gives the server a new format to use when
providing dates. This is a string compatible with the
strftime library call under most versions of UNIX.
sizefmt determines the formatting to be used when
displaying the size of a file. Valid choices are bytes,
for a formatted byte count (formatted as 1,234,567), or
abbrev for an abbreviated version displaying the number
of kilobytes or megabytes the file occupies.
Output Directives
The echo directive prints the value a variable to the
output stream.
<!--#echo var="variable_name" -->
The printenv directive prints all variables currently
set:
<!--#printenv -->
The output is a series of lines: variable=value. For debugging
purposes, you probably want to enclose this directing in a
<PRE> container.
The fsize directive prints the size of the specified file.
The resulting format of this command is subject to the
sizefmt parameter to the config command.
<!--#fsize virtual="URL" -->
<!--#fsize file="path" -->
virtual gives a URL reference (which may be relative)
to a document on the server. You must access a normal file this way,
you cannot access a CGI script in this fashion. You can, however,
access another parsed document.
file gives a pathname relative to the current
directory. ../ cannot be used in this pathname, nor can absolute paths
be used. As above, you can send other parsed documents, but you cannot
send CGI scripts.
The flastmod directive prints the last
modification date of the
specified file, subject to the formatting preference given by the
timefmt parameter to config.
<!--#flastmod virtual="URL" -->
<!--#flastmod file="path" -->
virtual gives a URL reference (which may be relative)
to a document on the server. You must access a normal file this way,
you cannot access a CGI script in this fashion. You can, however,
access another parsed document.
file gives a pathname relative to the current
directory. ../ cannot be used in this pathname, nor can absolute paths
be used. As above, you can send other parsed documents, but you cannot
send CGI scripts.
Flow Control Directives
The basic flow control directives in XSSI are:
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
The if directive works like an
if statement in a programming language. The test condition
is evaluated and if the result is true, then the text until
the next elif, else.
or endif directive is included in the
output stream.
The elif or else
statements are be used the put text into the output stream
if the original test_condition was false. These directives
are optional.
The endif statement ends the
if statement and is required.
test_condition is one of the following:
- string
- true if string is not empty
- string1 = string2
string1 != string2
- Compare string1 with string 2. If string2 has the form /string/
than it is compared as a regular expression.
Regular expressions have the same syntax as those found in the Unix
egrep command.
- ( test_condition )
- true if test_condition is true
- ! test_condition
- true if test_condition is false
test_condition1 and test_condition2 are true
- test_condition1 && test_condition2
- true if both
test_condition1 and test_condition2 are true
- test_condition1 || test_condition2
- true if either
test_condition1 or test_condition2 is true
= and != bind more tightly than && and ||.
! binds most tightly. Thus, the following are equivalent:
<!--#if expr="$a = test1 && $b = test2" -->
<!--#if expr="($a = test1) && ($b = test2)" -->
Anything that's not recognized as a variable or an operator is
treated as a string. Strings can also be quoted: 'string'.
Unquoted strings can't contain whitespace (blanks and tabs)
because it is used to seperate tokens such as variables. If
multiple strings are found in a row, they are concatenated using
blanks. So,
string1 string2 results in string1 string2
'string1 string2' results in string1 string2
Variable substitution is done within quoted strings. You can put
a dollar sign into the string using backslash quoting:
<!--#if expr="$a = \$test" -->
System Interaction Directives
The include directive inserts the text of a
document into the parsed document.
<!--#include virtual="URL" -->
<!--#include file="path" -->
virtual gives a URL reference (which may be relative)
to a document on the server. You must access a normal file this way,
you cannot access a CGI script in this fashion. You can, however,
access another parsed document.
file gives a pathname relative to the current
directory. ../ cannot be used in this pathname, nor can absolute paths
be used. As above, you can send other parsed documents, but you cannot
send CGI scripts.
The exec directive executes a given shell
command or CGI script (The server to recognize and execute
this directive).
<!--#exec cmd="command_string" -->
<!--#exec cgi="CGI_URL" -->
cmd will execute the given string using /bin/sh. All
of the variables defined below are defined, and can be used in the
command.
cgi will execute the given virtual path to a CGI
script and include its output. The server does not perform error
checking to make sure your script didn't output horrible things like a
GIF, so be careful. It will, however, interpret any URL Location:
header and translate it into an HTML anchor.
See the
NCSA Server Side Include Tutorial and the
APACHE Server Documentation
for instructions on how to configure the server to support
Server-Side includes.
Retrieve xssi and
follow the directions in the README file to install.
SSI Notes and Issues
XSSI-1.0 works for Apache 1.0.3 - 1.0.5. XSSI-1.1 works for Apache
1.1 and above. XSSI has been tested on SunOS 4.1.3 and Linux 1.3.57.
XSSI only works for the Apache
httpd server.
The following directives have been added to the
Standard SSI to create the XSSI:
<!--#set var="variable_name" value="variable_value"-->
<!--#printenv -->
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
The only place where they may be an incompatibility with the standard
SSI is if a tag value used a '$'. This should only have been possible
in a <!--#exec cmd="..." --> directive.
Having the server parse documents is a double edged sword. It can
be costly for heavily loaded servers to perform parsing of files
while sending them. Further, it can be considered a security risk
to have average users executing commands as the server's User. If
you disable the exec option, this danger is mitigated, but the
performance issue remains. You should consider these items
carefully before activating server-side includes on your server.
Acknowledgements
XSSI uses the regular expression package written by Henry Spencer,
as modified by Karl-Johan Johnsson the author of
knews.
If handling bug identified and patched by Vaughn Skinner .
|