O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


APACHE HACK

More Server Side Include Trickery
You know Server Side Includes have a decent amount of power under the hood, but you're not entirely sure what quickie trickies can be accomplished. Below, we'll touch on a number of simple SSI hacks that can be used for quick prototyping, simplistic logging or authentication, random file serving, and more.

Contributed by:
Morbus Iff
[03/14/03 | Discuss (3) | Link to this hack]

Prerequisites

  • The Server Side Include module (mod_includes) must be enabled.

Uh oh. Client XYZ wants authentication on their site. You're super busy, they're super anxious. You suggest .htaccess and .htpasswd protection, but they balk at the "unfriendly" authentication box that appears. They want it tomorrow, and you want tomorrow off. With quick SSI tweakery, you whip together the following:

{{{
   <!--#if expr="$QUERY_STRING = 'username=guest&password=anonymous'" -->
   <meta http-equiv="Refresh" content="1; URL=guest/index.shtml">

   <!--#elif expr="$QUERY_STRING = 'username=crazyhorse&password=719'" -->
   <meta http-equiv="Refresh" content="1; URL=special/index.shtml">

   <!--#else -->
   <meta http-equiv="Refresh" content="1; URL=oops.html">
   <!--#endif -->
}}}

The above file works as an interim redirector page. You'd have a login page called "login.html", for example, and in it, a form with two input fields called "username" and "password". The form would send the results to the above page, perhaps called "validate.html". The $QUERY_STRING is a key=value pair of all the data sent via the GET form method, and with the above code, we check for two different users: "guest" and "crazyhorse". If we see those usernames AND the correct passwords, then we send the browser a Refresh command to the right directory. If not, we send the browser to an "oops.html" page.

There are a few bad aspects of this hack:

  • passwords are stored in plain text in the validate.html file.
  • manual editing of the validate.html file can get annoying.
  • assumption that the QUERY_STRING will be in the same order each time.
  • the username and password is bookmarkable, which can be insecure.

It should, however, tide most simplistic authentication needs until they grease your palms with a bit more money. Of course, ever belligerent, they now want you to change the background color of the site based on the time of day - "sunny in the morning, nightlike at night!". You groan, but again, SSI comes to the rescue:

{{{
   <!--#config timefmt="%H" -->

   <!--#if expr="$DATE_LOCAL < 12" -->
    <body background="images/morning.gif">
   <!--#endif -->

   <!--#if expr="$DATE_LOCAL > 12 && $DATE_LOCAL < 18" -->
    <body background="images/afternoon.gif">
   <!--#endif -->

   <!--#if expr="$DATE_LOCAL > 18" -->
    <body background="images/evening.gif">
   <!--#endif -->
}}}

The "timefmt" configuration that we start out with will return all dates in the format we've specified which, in this case, is a zero padded hourly value, like "05" or "12". Our next lines of SSI merely check that hour to see if it's between a certain range of numbers - whatever time it is will have a different background image defined.

You can also modify the above to show a different message (or redirect to a different page, change background colors, etc.) base on what the current second is, producing a close approximation of a "random" element in your pages:

{{{
   <!--#config timefmt="%S" -->
>
     ... do something here ...
   <!--#elif expr="$DATE_LOCAL = /.1/" -->
     ... do something else here ...

    ...

>
     ... do something else entirely ...
   <!--#endif -->
}}}

Company XYZ doesn't stop, however, no matter how many fruit baskets you send. Now, they want a counter on their site, oh, those dreadful counters. You don't want to actually install a counter on your box (how sullied it would become!), but you can craft one simply with SSI.

{{{
   <!--#exec cmd=" N=`cat counter.dat` && expr $N + 1 > counter.dat"-->
> 
}}}

The first SSI command above runs a simple shell command line that gets the contents of a "counter.dat" file (which should exist, and contain the number that you want the counter to start at), and then adds 1 to it. The second SSI command will then echo the new contents of the file to the web browser.

Whether the above will work or not will really depend on what your primary shell is on your web server. Here's another example, simplified down to one line:

{{{
   <!--#exec cmd="echo $[`cat counter.dat`+1] | tee counter.dat"-->
}}}

The above are just a few of the tricks possible to SSI, and if you allow the "exec" command, you can start incorporating the power of common shell utilities (at the expense of lessened security).


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.