Apache Server Survival Guide asg06.htm
|
|
var="variable" | variable is the name of the variable to print. |
Beginning with Apache 1.1, the SSIs and CGIs you call from your SSI also have access to the CGI environment variables. For a complete listing, refer to Chapter 5, "CGI (Common Gateway Interface) Programming."
Beginning with Apache 1.2, Apache adopted the use of the XSSI module as their standard SSI processor. XSSI is discussed in detail in a section of this chapter entitled, "eXtended Server Side Includes (XSSI)."
The exec command executes the specified shell command or CGI program. This option can be disabled by the IncludesNOEXEC option. The valid options are
cgi="path" | path specifies the program to be run. If path is not an absolute path (one that begins with a /), then path is taken to be relative to the current document. |
The directory containing the program must be a CGI directory approved by either a ScriptAlias or by setting the ExecCGI option in the global access configuration file or on a per-directory access file. | |
The program's environment include the PATH_INFO and QUERY_STRING variables set to the values sent in the original request. The include variables are available to the script in addition to the standard CGI environment. | |
Programs that return a Location: header have their output translated into an HTML anchor. | |
Use of the include virtual element is preferred to exec cgi. | |
cmd="string" | The server will execute string using /bin/sh. The environment includes the include variables and, beginning with Apache 1.1, the complete set of CGI environment variables. |
This command inserts the size of the specified file, subject to the sizefmt format specification. The options to this command are
file="path" | The value is a path relative to the directory containing the current document being parsed. |
virtual="path" | If path is not an absolute path (one that begins with a (/), path is taken to be relative to the current document. |
This command inserts the last modification date of the specified file, subject to the timefmt format specification. The options for this command are
file="path" | The value is a path relative to the directory containing the current document being parsed. |
virtual="path" | If path is not an absolute path (one that begins with a (/), it is taken to be relative to the current document. |
|
file="filename" | filename is a filename relative to the directory containing the current document being parsed. It cannot contain ../, nor can it be an absolute path. The virtual option should always be used in preference to this one. |
virtual="urlpath" | urlpath is a path relative to the current document being parsed. The URL cannot contain a scheme or hostname, only a path and an optional query string. If urlpath is not an absolute path (one that begins with a /), path is taken to be relative to the current document. |
A URL is constructed from the option, and the output the server would return if the URL were accessed by the client is included in the parsed output; included files can be nested. |
These variables are provided for includes and to any program invoked by the document:
DATE_GMT | The current date in Greenwich Mean Time (GMT). |
DATE_LOCAL | The current date in the local time zone. |
DOCUMENT_NAME | The filename of the document requested by the user. DOCUMENT_NAME does not include any path information. |
DOCUMENT_URI | The path of the document requested by the user. |
LAST_MODIFIED | The document's last modification date. |
[ic:Apache 1.1]In Apache 1.1, you can access the CGI environment variables (for a complete list, refer to Chapter 5) in addition to the include variables. The standard CGI 1.1 specification defines the several variables. Some are filled for all requests (SERVER_SOFTWARE, SERVER_NAME, and GATEWAY_INTERFACE). Others are request specific and may not be defined. A third category is added by the client program. These variables start with HTTP.
With this information you can create some pretty useful SPML pages that start to act more like a CGI program than a SPML. Two omissions from the Apache SSI module are conditional execution and user-defined variables. Howard Fear has developed a full replacement for the Apache SSI module, adding this missing functionality. This module is called XSSI. It is available from the CD-ROM included with this book, and is part of the standard Apache distribution for 1.2, which at the time this book was written, is yet unavailable.
Here's an example, shown in Listing 6.1 and then in Figure 6.1, that puts it all together. You may want to implement something like this on your own site. The page returned is generated at random, based on a small database of quotes (in my programs the database is referred to as quotes.conf). Each entry in the database is a single line of text. Each record in the quote database is separated by a newline.
Listing 6.1. quote.shtml.
<HTML> <HEAD> <TITLE> Random Quote </TITLE> </HEAD> <BODY> <P ALIGN=CENTER> <FONT SIZE=7><EM>Random Quote</EM></FONT> </P> <HR> <BLOCKQUOTE> <FONT SIZE=5><EM> <!--#exec cmd="cgi/quoteoftheday.cgi"--> </EM> </FONT> </BLOCKQUOTE> <HR> <!--#exec cmd="cgi/envvar.cgi"--> <P> <!--#config timefmt="%A, %B %d %Y"--> <!--#echo var="DATE_LOCAL"--> </BODY> </HTML> |
The quoteoftheday.cgi program returns a random line from the quote database (see Listing 6.2). The quote database is just a simple text file with one quote per line. The CGI returns one line, which the server inserts into the HTML stream returned to the client.
Listing 6.2. quoteoftheday.cgi.
|
#!/usr/local/bin/perl -w # # quote.cgi - prints a quote at random # $conf_file: the absolute path to your configuration file # $ad_tag: the string outputted to the web page SSI location # Call this script from a server-parsed html document (.shtml for example) and make # sure that server-side includes are enabled. # # Use the following example code: # <!--#exec cmd="/yourpath/random.cgi"--> # # Of course, substitute your actual path to the random.cgi for / yourpath. Again, # this won't work unless Server-Side Includes are activated for Apache... use strict; # Declare all our variables before using them $| = 1; # Flush the output buffer #Variables my( $conf_file, $quote ); my( @Quotes ); my( $num_quotes, $rand_quote ); $conf_file = "/NextLibrary/WebServer/htdocs/AccessLink.htmld/cgi/quotes.conf"; srand; open( IN, $conf_file ) || die "Cannot open $conf_file: $!"; @Quotes = <IN>; close( IN ); $num_quotes = @Quotes; #How many quotes are there? $rand_quote = int( rand( $num_quotes - 1 ) ); $quote = $Quotes[$rand_quote]; print $quote; exit( 0 ); |
Finally, envvar.cgi is a trivial Perl program that prints out two of my CGI environment variables. (See Listing 6.3.) If you are using Apache 1.1.1's SSI module or XSSI, CGI variables are available as any of the standard SSI variables, so there's no need for this program.
Listing 6.3. envvar.cgi.
|
#!/usr/local/bin/perl -w # use strict; # Declare all our variables before using them $| = 1; # Flush the output buffer print "HTTP_USER_AGENT = $ENV{HTTP_USER_AGENT}<BR>\n"; print "REMOTE_ADDR = $ENV{REMOTE_ADDR}<BR>\n"; |
|
<!--#set var="variableName" value="variable_value"--> |
For example, to define a variable program that holds the value "/cgi-bin/printenv", you would set the following:
|
<!--#set var="program" value="/cgi-bin/printenv" --> |
You can then use this variable on any value tag, except on the var=tags:
|
<!--#exec cgi="$program" --> |
Alternatively, you can specify additional arguments by enclosing the variable in braces like the following:
|
<!--#exec cgi="${program} additional_text"--> |
In addition to the variables defined for SSI, you can use any of the CGI environment variables (for a complete listing of these variables, please refer to the Chapter 5), which help create very simple, yet powerful, SSI programs without the need to write a CGI program.
It's worth noting that the $ syntax to denote variable names may cause problems in exec cmd constructs where the $ may be used by another program to denote an argument. For example:
|
<!--#exec cmd="/usr/local/etc/httpd/cgi-bin/finger @${HOST_NAME} |/bin/ awk '{print $1}'" --> |
This SSI won't work as expected. The $1 is set to a null value, which causes awk to print the complete line instead of the first word as intended. The solution to this minor inconveniece is to have an sh script handle all the output properly and return the data to you.
|
<!--#if expr="condition" --> <!--#elif expr="condition" --> <!--#else --> <!--#endif --> |
The if constructs work as they do in any programming language. If condition evaluates to true, all text specified until the next elif, else, or endif is included in the output. If condition evaluates to false, text specified after the else statement is included in the output.
The elif condition is evaluated if the preceding if statement evaluated to false. Statements specified after an elif statement are included in the output if the elif expression evaluates to true.
All conditional constructs must be terminated by an endif construct.
Any token that is not recognized as a variable or an operator is treated as a string. Strings can be quoted; variable substitution is done within quoted strings (if you need a $ within a string, you can escape it by preceding it with a backslash (\) character). Unquoted strings cannot contain whitespace because spaces are used to separate other tokens. condition can be any of the following:
More interesting than a straight comparison is that XSSI allows you to test using regular expressions that follow the UNIX egrep syntax. In Table 6.1, character excludes newline.
The following example shows you how to output HTML based on the browser detected:
|
<!--#if expr="${HTTP_USER_AGENT} = /Mozilla/" --> Output NETSCAPE specific HTML <!--#else --> Output HTML 2.0 compliant formatting <!--#endif --> |
|