---
name: "Apache::SSI"
section: "3pm"
platform: "linux"
package: "libapache-ssi-perl"
version: "2.19-2"
release: "Debian 4.0 (Etch)"
platforms: ["linux"]
url: "https://new.carta.tech/Apache::SSI"
---

# Apache::SSI(3pm)

Apache::SSI - Implement Server Side Includes in Perl In httpd.conf:

```
    <Files *.phtml>  # or whatever
    SetHandler perl-script
    PerlHandler Apache::SSI
    </Files>
```

You may wish to subclass Apache::SSI for your own extensions.  If so, compile mod\_perl with PERL\_METHOD\_HANDLERS=1 (so you can use object-oriented inheritance), and create a module like this:

```
    package MySSI;
    use Apache::SSI ();
    @ISA = qw(Apache::SSI);
```

```
    #embedded syntax:
    #<!--#something param=value -->
    sub ssi_something {
       my($self, $attr) = @_;
       my $cmd = $attr->{param};
       ...
       return $a_string;
    }
```

```
 Then in httpd.conf:
```

```
    <Files *.phtml>
     SetHandler perl-script
     PerlHandler MySSI
    </Files>
```

Apache::SSI implements the functionality of mod\_include for handling server-parsed html documents.  It runs under Apache's mod\_perl. In my mind, there are two main reasons you might want to use this module: you can sub-class it to implement your own custom SSI directives, and/or you can parse the output of other mod\_perl handlers, or send the SSI output through another handler (use Apache::Filter to do this). Each SSI directive is handled by an Apache::SSI method with the prefix "ssi\_".  For example, \<!--#printenv--\> is handled by the ssi\_printenv method. attribute=value pairs inside the SSI tags are parsed and passed to the method in a hash reference. 'Echo' directives are handled by the ssi\_echo method, which delegates lookup to methods with the prefix "echo\_".  For instance, \<!--#echo var=DOCUMENT\_NAME--\> is handled by the echo\_DOCUMENT\_NAME method. You can customize behavior by inheriting from Apache::SSI and overriding 'ssi\_\*' and 'echo\_\*' methods, or writing new ones.\
 **SSI Directives** This module supports the same directives as mod\_include.  At least, that's the goal. =)  For methods listed below but not documented, please see mod\_include's online documentation at http://www.apache.org/ . There are two ways to call a Perl function, and two ways to supply it with arguments.  The function can be specified either as an anonymous subroutine reference, or as the name of a function defined elsewhere:

```
 <!--#perl sub="sub { localtime() }"-->
 <!--#perl sub="time::now"-->
```

If the 'sub' argument matches the regular expression /^\\s\*sub\[^\\w:\]/, it is assumed to be a subroutine reference.  Otherwise it's assumed to be the name of a function.  In the latter case, the string "main::" will be prepended to the function name if the name doesn't contain "::" (this forces the function to be in the main package, or a package you specify).  Note that it's a pretty bad idea to put your code in the main package, so I only halfheartedly endorse this feature.

In general, it will be slower to use anonymous subroutines, because each one has to be *eval()*'ed and there is no caching.  For best results, pre-load any code you need in the parent process, then call it by name.

If you're calling a subroutine like "&Package::SubPack::handler", you can omit the "handler" portion, making your directive like this:

```
 <!--#perl sub="Package::Subpack"-->
```

If you want to supply a list of arguments to the function, you use either the "arg" or the "args" parameter:

```
 <!--#perl sub="sub {$_[0] * 7}" arg=7-->
 <!--#perl sub=holy::matrimony arg=Hi arg=Lois-->
 <!--#perl sub=holy::matrimony args=Hi,Lois-->
```

The "args" parameter will simply split on commas, meaning that currently there's no way to embed a comma in arguments passed via the "args" parameter.  Use the "arg" parameter for this.

If you give a key-value pair and the key is not 'sub', 'arg', 'args', or  'pass\_request' (see below), then your routine will be passed **both** the  key and the value.  This lets you pass a hash of key-value pairs to your  function:

```
 <!--#perl sub=holy::matrimony groom=Hi bride=Lois-->
 Will call &holy::matrimony('groom', 'Hi', 'bride', 'Lois');
```

As of version 1.95, we pass the current Apache request object ($r) as the first argument to the function.  To turn off this behavior, give the key-value pair 'pass\_request=no', or put 'PerlSetVar SSIPerlPass\_Request no' in your server's config file.

See `"http://perl.apache.org/src/mod_perl.html"` for more information on Perl SSI calls. These four directives can be used just like in `"mod_include"`, with one important difference: the boolean expression is evaluated using Perl's *eval()*.  This means you use `"=="` or `"eq"` instead of `"="` to test equality.  It also means you can use pre-loaded Perl subroutines in the conditions:

```
 <!--#if expr="&Movies::is_by_Coen_Brothers($MOVIE)"-->
  This movie is by the Coen Brothers.
 <!--#else-->
  This movie is not by the Coen Brothers.
 <!--#endif-->
```

It can't handle very sophistocated Perl though, because it manually looks for variables (of the form `$var` or ${var}, just like `"mod_include"`), and will get tripped  up on expressions like `$object`-\>method or `$hash`{'key'}.  I'll welcome any suggestions for how to allow arbitrary Perl expressions while still filling in Apache variables. There are two fairly simple ways for this module to exist in a stacked handler chain.  The first uses `"Apache::Filter"`, and your httpd.conf would look something like this:

```
 PerlModule Apache::Filter
 PerlModule Apache::SSI
 PerlModule My::BeforeSSI
 PerlModule My::AfterSSI
 <Files ~ "\.ssi$">
  SetHandler perl-script
  PerlSetVar Filter On
  PerlHandler My::BeforeSSI Apache::SSI My::AfterSSI
 </Files>
```

The `"PerlSetVar Filter On"` directive tells the three stacked handlers that they should use their filtering mode.  It's mandatory. The second uses `"Apache::OutputChain"`, and your httpd.conf would look something like this:

```
 PerlModule Apache::OutputChain
 PerlModule Apache::SSIChain
 PerlModule My::BeforeSSI
 PerlModule My::AfterSSI
 <Files ~ "\.ssi$">
  SetHandler perl-script
  PerlHandler Apache::OutputChain My::AfterSSI Apache::SSIChain My::BeforeSSI
 </Files>
```

Note that the order of handlers is reversed in the two different methods.  One  reason I wrote `"Apache::Filter"` is to get the order to be more intuitive.   Another reason is that `"Apache::SSI"` itself can be used in a handler stack using `"Apache::Filter"`, whereas it needs to be wrapped in `"Apache::SSIChain"` to  be used with `"Apache::OutputChain"`. Please see the documentation for `"Apache::OutputChain"` and `"Apache::Filter"` for more specific information.  And look at the note in CAVEATS too. \* When chaining handlers via Apache::Filter, if you use \<!--#include ...--\> or \<!--#exec cgi=...--\>, then Apache::SSI must be the last filter in the chain.  This is because Apache::SSI uses `$r`-\>lookup\_uri(...)-\>run to include the files, and this sends the output through C's stdout rather than Perl's STDOUT.  Thus Apache::Filter can't catch it and filter it. If Apache::SSI is the last filter in the chain, or if you stick to simpler SSI directives like \<!--#fsize--\>, \<!--#flastmod--\>, etc. you'll be fine. \* Currently, the way \<!--#echo var=whatever--\> looks for variables is to first try `$r`-\>subprocess\_env, then try `%ENV`, then the five extra environment variables mod\_include supplies.  Is this the correct order? Revisit http://www.apache.org/docs/mod/mod\_include.html and see what else there I can implement. It would be nice to have a "PerlSetVar ASSI\_Subrequests 0⎪1" option that would let you choose between executing a full-blown subrequest when including a file, or just opening it and printing it. I'd like to know how to use Apache::test for the real.t test. mod\_include, *mod\_perl*(3), *Apache*(3), [*HTML::Embperl*(3)](/HTML::Embperl/3.md), *Apache::ePerl*(3), *Apache::OutputChain*(3) Ken Williams ken@mathforum.org Concept based on original version by Doug MacEachern dougm@osf.org . Implementation different. Copyright 1998 Swarthmore College.  All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
