Server Side Parsing

Dynamic Page Rendering
As of 1.32, SSIs (server side includes) and server side scripting (PHP, ASP, etc.) can be rendered in dynamically generated pages (search.cgi and view.cgi results). Any pages generated dynamically will behave almost exactly like your static, published pages.

Previously (using the old "template include" system) scripting could not be rendered and includes were parsed only through Article Manager's special "template include" tags.

Activation - Login to Article Manager's Setup Options/General and select "Resolve SSIs and Server-side Scripting" from the Dynamic Page Rendering options.

Includes - If you are an upgrade user refitting your templates for this feature, you might need to add SSI tags to some pages that are missing them. But in most cases your SSIs and "template includes" should both be in the same templates. You do not need to remove "template includes" - they will simply be ignored. For more information on using includes with Article Manager, see the Includes documentation.

Scripting - Server-side scripts can be in your templates, or referenced from external files via includes. The extension of your publish files (configured in Setup Options/Server in Publish Settings) must be compatible with your scripts (see "how it works" below).

How it works - Temporary pages
When search.cgi or view.cgi is called, Article Manager generates a temporary, static file, then requests that temp file from your webserver, allowing your webserver to resolve any SSIs or server side code. The temp file is then deleted. (For debugging purposes, you can disable the deletion of these temp files in the config.ini file.)

Dynamic pages will be interpreted based on the "Publish file extension" setting in the setup options - i.e. if your published pages are being created as .asp files, the server will interpret your dynamically-generated pages as .asp files also. The extension is used by your server to determine whether to render SSI (.shtml on most servers), and whether to parse scripting in the page (.php or .asp).

Known Issues

Stats anomalies
Your server statistics will record the dynamic requests for the temp page (see above) as an additional server hit, affecting your stats. Your stats program should be able to offset this effect by filtering the server's IP address. Contact your server administrator for more information.

Password Protected Publish Folder
If Article Manager's publish folder is password protected, search.cgi and view.cgi (and admin.cgi's "preview" feature) require login access in order to render results correctly. You set this password in Setup Options/General.

This is necessary because Article Manager renders the dynamic page by creating a temporary file in the publish directory - search.cgi needs read access to that temp file if it is password protected because it makes the request it on behalf of the browser.

If they are not already, you may also wish to password protect exec/view.cgi and exec/search.cgi. When you provide view.cgi and search.cgi with login access, users will be able to use these scripts, even if they are not logged in. Password protecting view.cgi and search.cgi will prevent this potential unauthorized access to your password protected article content and summaries.

Advanced issue: Tracking client IP address
Because Article Manager is doing the web request on behalf of the client, the IP address reported is the server's IP address. Any scripting that you have for capturing the client's IP address will receive the server's IP addresses instead. To compensate, Article Manager transmits custom HTTP headers with the original client's IP address.

The custom headers provided by Article Manager for this purpose are HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR. Since HTTP headers can be spoofed, these headers should only be trusted if the request is reported as coming from the server itself.

Below is some sample Perl code to demonstrate how these custom headers may be captured.

Sample Perl Code
### Determine original client's IP (respect proxied IPs)
my $client_ip = $ENV{'REMOTE_ADDR'};
my $server_ip = $ENV{'SERVER_ADDR'} || $ENV{'LOCAL_ADDR'};
if ($client_ip eq $server_ip) {
  $client_ip = $ENV{'HTTP_X_FORWARDED_FOR'} ||
               $ENV{'HTTP_CLIENT_IP'} ||
               $ENV{'REMOTE_ADDR'};
}
 
### Overwrite ENV var with original client's IP
$ENV{'REMOTE_ADDR'} = $client_ip;