Red Hat Linux 7 Unleashed

Red Hat Linux 7 Unleashed

By William Ball

Dynamic Content

The most common way to provide dynamic content on Web sites is with CGI (Common Gateway Interface) programs. The CGI is a specification of communication between server processes (such as programs that generate dynamic documents) and the server itself. Server-Side Includes (SSIs) allow output from CGI programs, or other programs, to be inserted into existing HTML pages.

Another way to add dynamic content to your Web site is to use PHP. This is an HTML-embedded scripting language that was designed specifically for Web usage. The PHP module for Apache is one of the most popular third-party modules available.

CGI

By default, you may put any CGI program in the ScriptAlias directory on your server. These programs must be executable by the user as which the server is running. This usually means that you will need to change the mode of the files to 555 so that the user whom Apache is running as can execute them. The default in Red Hat is that Apache runs as a user named apache.

chmod 555 program.cgi

In order to execute CGI programs outside of the ScriptAlias directory, you will need to enable the ExecCGI option for that directory. This is done either in your httpd.conf file (access.conf prior to version 1.3.4) or in an .htaccess file in the directory.

CGI programs can be written in any language. The most popular languages for CGI programming are Perl and C. You may want to pick up a good book on CGI programming, such as CGI Programming With Perl, Second Edition, since this is not intended to be a CGI book.

To test whether you have CGI configured correctly, try the CGI program in Listing 12.1, written in Perl, which displays the values of the HTTP environment variables.

Example 12.1. environment.pl

#!/usr/bin/perl -w

print <<EOF;
"Content-type: text/html

<HTML>
 <HEAD>
  <TITLE>Simple CGI program</TITLE>
 </HEAD>
 <BODY>
EOF
for (keys %ENV)    {
    print "  $_ = $ENV{ $_} <BR>\n";
}
print <<EOF;
 </BODY>
</HTML>
EOF

If you are going to be writing CGI programs in Perl, you may want to look at the CGI modules that come bundled with Perl. There is also an extensive module library for Perl, which contains many modules designed to be used when writing CGIs. The archive can be accessed at http://www.cpan.org.

If you are using many CGIs written in Perl you may want to look into the mod_perl module. It embeds a Perl interpreter within the Apache server. This will result in faster execution times for your CGIs because there will be no need to start up a new Perl interpreter for each request. However, this will make the memory footprint of each Apache process much larger.

SSI

Server- Side Includes (SSIs) are directives written directly into an HTML page, which the server parses when the page is served to the Web client. They can be used to include other files, the output from programs, or environment variables.

The most common way to enable SSI is to indicate that files with a certain filename extension (typically .shtml) are to be parsed by the server when they are served. This is accomplished with the following lines in your httpd.conf file (srm.conf prior to version 1.3.4):

# To use server-parsed HTML files
#
#AddType text/html .shtml
#AddHandler server-parsed .shtml

If you uncomment the AddType and AddHandler lines, you will tell the server to parse all .shtml files for SSI directives.

The less commonly used, but in my opinion much better, way of enabling SSI is with the XBitHack directive. XBitHack can be set to a value of on or off, and can be set in either your configuration file or in .htaccess files. If the XBitHack directive is on, it indicates that all files with the user execute bit set should be parsed for SSI directives. This has two main advantages. One is that you do not need to rename a file, and change all links to that file, simply because you want to add a little dynamic content to it. The other reason is more cosmetic—users looking at your Web content cannot tell by looking at the filename that you are generating a page dynamically, and so your wizardry is just that tiny bit more impressive.

Another positive side effect of using XBitHack is that it enables you to control how clients should cache your page. Usually pages containing SSI statements will not contain a Last-modified HTTP header. Therefore they will not be cached by proxies nor Web browsers. If you enable XBitHack, the group-execute bit for files will control whether or not a Last-modified header should be generated. It will be set to the same value as the last modified time of the file. Be sure to use this only on files that really are supposed to be cached.

In addition to these directives, the following directive must be specified for directories where you want to permit SSI:

Options Includes

This may be set in the server configuration file or in an .htaccess file.

Basic SSI Directives

SSI directives look rather like HTML comment tags. The syntax is as follows:

<!--#element attribute=value attribute=value ... -->

The element can be one of the following:

config This lets you set various configuration options regarding how the document parsing is handled. Because the page is parsed from top to bottom, config directives should appear at the top of the HTML document. There are three configurations that can be set with this command:
  errmsg Sets the error message that is returned to the client if something goes wrong while parsing the document. This is usually [an error occurred while processing this directive], but it can be set to anything with this directive.
    Example: <!--#config errmsg="[It's broken, dude]" -->
  sizefmt Sets the format used to display file sizes. You can set the value to bytes to display the exact file size in bytes, or abbrev to display the size in KB or MB.
    Example: <!--#config sizefmt="bytes" -->
  timefmt Sets the format used to display times. The format of the value is the same as is used in the strftime function used by C (and Perl) to display dates, shown in the following table.
    %% Format
    %a Day of the week abbr.
    %A Day of the week
    %b Month abbr.
    %B Month
    %c ctime format: Sat Nov 19 21:05:57 1994
    %d Numeric day of the month
    %e DD
    %D MM/DD/YY
    %h Month abbr.
    %H Hour, 24-hour clock, leading 0's
    %I Hour, 12-hour clock, leading 0's
    %j Day of the year
    %k Hour
    %l Hour, 12-hour clock
    %m Month number, starting with 1
    %M Minute, leading 0's
    %n NEWLINE
    %o Ornate day of month—1st, 2nd, 25th, and so on
    %p AM or PM
    %r Time format: 09:05:57 PM
    %R Time format: 21:05
    %S Seconds, leading 0's
    %t Tab
    %T Time format: 21:05:57
    %U Week number; Sunday as first day of week
    %w Day of the week, numerically; Sunday == 0
    %W Week number; Monday as first day of week
    %x Date format: 11/19/94
    %X Time format: 21:05:57
    %y Year (2 digits)
    %Y Year (4 digits)
    %Z Time zone in ASCII, such as PST
echo Displays any one of the include variables, listed below. Times are displayed in the time format specified by timefmt. The variable to be displayed is indicated with the var attribute.
  DATE_GMT The current date in Greenwich Mean Time.
  DATE_LOCAL The current date in the local time zone.
  DOCUMENT_NAME The filename (excluding directories) of the document requested by the user.
  DOCUMENT_URI The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not the URL for the current document.
  LAST_MODIFIED The last modification date of the document requested by the user.
exec Executes a shell command or a CGI program, depending on the parameters provided. Valid attributes are cgi and cmd.
  cgi The URL of a CGI program to be executed. The URL needs to be a local CGI, not one located on another machine. The CGI program is passed the QUERY_STRING and PATH_INFO that were originally passed to the requested document, so the URL specified cannot contain this information. You should really use include virtual instead of this directive.
  cmd A shell command to be executed. The results will be displayed on the HTML page.
fsize Displays the size of a file specified by either the file or virtual attribute. Size is displayed as specified with the sizefmt directive.
  file The path (filesystem path) to a file, either relative to the root if the value starts with /, or relative to the current directory if not.
  virtual The relative URL path to a file.
flastmod Displays the last modified date of a file. The desired file is specified as with the fsize directive.
include Includes the contents of a file. The file is specified with the file and virtual attributes, as with fsize and flastmod. If the file specified is a CGI program and IncludesNOEXEC is not set, the program will be executed and the results displayed. This is to be used in preference to the exec directive. You can pass a QUERY_STRING with this directive, which you cannot do with the exec directive.
printenv Displays all existing variables. There are no attributes.
  Example: <!--#printenv -->
set Sets the value of a variable. Attributes are var and value.
  Example: <!--#set var="animal" value="cow" -->

These variables can be used elsewhere with some of the following directives.

Flow Control

Using the variables set with the set directive and the various environment variables and include variables, there is a limited flow control syntax that can be used to generate a certain amount of dynamic content on server-parsed pages.

The syntax of the if/else functions is as follows:

<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->

expr can be a string, which is considered true if non-empty, or a variety of comparisons between two strings. Available comparison operators are =, !=, <, <=, >, and >=. If the second string has the format /string/, the strings are compared with regular expressions. Multiple comparisons can be strung together with && (AND) and || (OR). Any text appearing between the if/elif/else directives will be displayed on the resulting page. An example of such a flow structure follows:

<!--#set var="agent" value="$HTTP_USER_AGENT" -->
<!--#if expr="$agent = /Mozilla/" -->
Mozilla!

<!--#else -->
Something else!
<!--#endif -->

This code will display "Mozilla!" if you are using a browser that passes Mozilla as part of its USER_AGENT string, and "Something else!" otherwise.

PHP

PHP can to some extent be seen as a mixture of the CGI and SSI. It is embedded in HTML as is SSI, but it provides full and rich language features. The syntax of PHP is largely inspired by C and Perl. There are also several PHP-specific features. It allows developers to rapidly design and write applications for usage on the Web.

You can use PHP with Apache in two ways. The first approach is to use it as a script engine that is run as a CGI program—much the same way as Perl is commonly used for CGIs. The other, and far superior, way is to use the mod_php approach. This will embed PHP within Apache. Therefore, there will be no overhead to start up PHP when an application is run. It will, however, add to the memory footprint of the Apache processes.

The mod_php module is included in the Red Hat distribution. You can test if it has been installed properly on your system by using this code snippet in your Web.

<HTML>
 <HEAD>
 <TITLE>Testing PHP</TITLE>
 </HEAD>
 <BODY>
  <H1>Testing PHP</H1>
  <P>If you have PHP installed, you'll get a greeting;</P>
  <?php print "Hello world!"; ?>
 </BODY>
</HTML>

PHP has far too many features to go into it in this chapter, especially since this is not a chapter on programming. However, there are several excellent PHP resources available online. The best place to start is http://www.php.net.

Share ThisShare This

Informit Network