summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2014-10-14 21:17:47 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2014-10-14 21:17:47 +0100
commit1fdff7a69a23fbbfda079dd13d4adad649bf980a (patch)
tree5442609a83e269797510860fe0073da8a740acb8
parentc23e07a1a121a49d973943dc9cb8c42c72bb1b4c (diff)
downloadnetsurf-website-1fdff7a69a23fbbfda079dd13d4adad649bf980a.tar.gz
netsurf-website-1fdff7a69a23fbbfda079dd13d4adad649bf980a.tar.bz2
Remove unused SSI FCGI script.
-rwxr-xr-xcgissi.fcgi638
1 files changed, 0 insertions, 638 deletions
diff --git a/cgissi.fcgi b/cgissi.fcgi
deleted file mode 100755
index 09e3c5e..0000000
--- a/cgissi.fcgi
+++ /dev/null
@@ -1,638 +0,0 @@
-#!/usr/bin/perl
-
-# \file
-# cgissi.fcgi -- A FastCGI script to emulate Server-Side Includes
-#
-# At the time of writing, it supports #include, #fsize and #flastmod
-#
-
-use warnings;
-use strict;
-
-use Digest::MD5 qw(md5_base64);
-use File::Spec;
-use FCGI;
-use POSIX qw(strftime);
-
-# Content cache to avoid regenerating pages unless it's absolutely necessary
-#
-# This hash maps between the full local path to the URL data
-# and a hash containing cache data. For example:
-#
-# { "/foo/bar/baz" =>
-# { last_modified => 0123456789,
-# data_digest => "base64(MD5($data))"
-# data_last_modified => 0123456789,
-# data => "generated page content",
-# dependencies =>
-# { "/foo/bar/bat" =>
-# { last_modified => 0123456789,
-# commands =>
-# [
-# { command => "include" | "fsize" | "flastmod",
-# start_offset = 123,
-# end_offset = 456
-# },
-# { command => "include" | "fsize" | "flastmod",
-# start_offset = 678,
-# end_offset = 901
-# }
-# ]
-# }
-# }
-# }
-# }
-#
-my %cache;
-
-# Request object
-my $request = FCGI::Request();
-
-# Loop until the server tells us to quit
-while ($request->Accept() >= 0) {
- # Get document root for this request
- my $docroot = $ENV{DOCUMENT_ROOT};
-
- # Get path of item for this request
- # Yes, this is hacky. It appears that REDIRECT_PATH contains
- # the destination document resulting from content negotiation.
- # As this is an absolute path, we strip the document root from it.
- my ($path) = ($ENV{REDIRECT_PATH} =~ m/$docroot(.*)/);
-
- # Find item in cache
- my $cachedata = $cache{$docroot . $path};
-
- # Determine if we need to (re)generate page
- validate_cache_entry($docroot, $path, $cachedata);
-
- # Refetch cache entry
- # (as it may have been created by validate_cache_entry)
- $cachedata = $cache{$docroot . $path};
-
- # TODO It would be nice to send 304 responses where appropriate
- # and also to pay attention to conditional requests namely
- # If-(None-)Match and If-(Un)Modified-Since
-
- # Cache-related headers
- print "ETag: " . $$cachedata{data_digest} . "\r\n";
- # Don't use %Z here, as perl's strftime appears to assume that the
- # time is always in the local timezone
- print "Last-Modified: " . strftime("%a, %d %b %Y %H:%M:%S GMT",
- gmtime($$cachedata{data_last_modified})) . "\r\n";
-
- # Send Content-Type header
- print "Content-Type: text/html; charset=ISO-8859-1\r\n";
- print "\r\n";
-
- # And the page data
- print $$cachedata{data};
-}
-
-################################################################################
-
-# Run an include command
-#
-# \param filepath The full path of the file to include
-# \param data Data buffer to append file data to (reference)
-#
-sub do_include
-{
- my ($filepath, $data) = @_;
-
- if (-e $filepath) {
- # Unlike Zeus, we don't recursively apply SSI.
- open FILE, $filepath;
- {
- local $/ = undef;
- $$data .= <FILE>;
- }
- close FILE;
- }
-}
-
-# Run a fsize command
-#
-# \param filepath The full path of the file to measure the size of
-# \param data Data buffer to append size to (reference)
-#
-sub do_fsize
-{
- my ($filepath, $data) = @_;
- my @units = ( "B", "kB", "MB", "GB", "TB" ); # should be sufficient ;)
-
- if (-e $filepath) {
- my $size = -s $filepath;
- my $index = 0;
-
- while ($size > 1000) {
- $size /= 1024;
- $index++;
- }
-
- $$data .= sprintf("%.1f %s", $size, $units[$index]);
- }
-}
-
-# Run a flastmod command
-#
-# \param filepath The full path of the file to get the modification time of
-# \param data Data buffer to append modification time to (reference)
-#
-sub do_flastmod
-{
- my ($filepath, $data) = @_;
-
- if (-e $filepath) {
- my $mod_string =
- strftime("%d %b %Y %R", gmtime((stat($filepath))[9]));
-
- $$data .= $mod_string . " UTC";
- }
-}
-
-# Process an include command
-#
-# \param command The command string to process
-# \param data Data buffer to append output to (reference)
-# \param docroot The document root
-# \param path Path of the current document, relative to ::docroot
-# \return The full path of the included file
-#
-sub process_include_command
-{
- my ($command, $data, $docroot, $path) = @_;
- my $filepath;
-
- if ($command =~ /file=/) {
- my ($relpath) = ($command =~ m/file="(.*)"/);
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($relpath,
- File::Spec->catpath($vol, $dirs, ""));
- } elsif ($command =~ /virtual=/) {
- my ($vpath) = ($command =~ m/virtual="(.*)"/);
- if ($vpath =~ m#^/.*#) {
- $filepath = $docroot . $vpath;
- } else {
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($vpath,
- File::Spec->catpath($vol, $dirs, ""));
- }
- }
-
- do_include($filepath, $data);
-
- return $filepath;
-}
-
-# Process an fsize command
-#
-# \param command The command string to process
-# \param data Data buffer to append output to (reference)
-# \param docroot The document root
-# \param path Path of the current document, relative to ::docroot
-# \return The full path of the included file
-#
-sub process_fsize_command
-{
- my ($command, $data, $docroot, $path) = @_;
- my $filepath;
-
- if ($command =~ /file=/) {
- my ($relpath) = ($command =~ m/file="(.*)"/);
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($relpath,
- File::Spec->catpath($vol, $dirs, ""));
- } elsif ($command =~ /virtual=/) {
- my ($vpath) = ($command =~ m/virtual="(.*)"/);
- if ($vpath =~ m#^/.*#) {
- $filepath = $docroot . $vpath;
- } else {
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($vpath,
- File::Spec->catpath($vol, $dirs, ""));
- }
- }
-
- do_fsize($filepath, $data);
-
- return $filepath;
-}
-
-# Process an flastmod command
-#
-# \param command The command string to process
-# \param data Data buffer to append output to (reference)
-# \param docroot The document root
-# \param path Path of the current document, relative to ::docroot
-# \return The full path of the included file
-#
-sub process_flastmod_command
-{
- my ($command, $data, $docroot, $path) = @_;
- my $filepath;
-
- if ($command =~ /file=/) {
- my ($relpath) = ($command =~ m/file="(.*)"/);
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($relpath,
- File::Spec->catpath($vol, $dirs, ""));
- } elsif ($command =~ /virtual=/) {
- my ($vpath) = ($command =~ m/virtual="(.*)"/);
- if ($vpath =~ m#^/.*#) {
- $filepath = $docroot . $vpath;
- } else {
- my ($vol, $dirs, $file) =
- File::Spec->splitpath($docroot . $path);
- $filepath = File::Spec->rel2abs($vpath,
- File::Spec->catpath($vol, $dirs, ""));
- }
- }
-
- do_flastmod($filepath, $data);
-
- return $filepath;
-}
-
-# Complete parsing of and process a command string
-#
-# \param template Open file handle of template input
-# \param char Current input character
-# \param command The command string read so far
-# \param data Buffer to append data into (reference)
-# \param docroot The document root
-# \param path Path of the current document relative to ::docroot
-# \param start_offset Offset into template input of start of SSI command
-# \param cacheentry The cache entry for the current document
-#
-sub process_command
-{
- my ($template, $char, $command, $data,
- $docroot, $path, $start_offset, $cacheentry) = @_;
- my $keyword = lc($command);
- my $dash_count = 0;
- my $filepath;
-
- # See state machine documentation in generate_page_full for details of
- # how this function works.
-
- # Reject command if it's one we know nothing about
- if ($keyword ne "include" && $keyword ne "fsize" &&
- $keyword ne "flastmod") {
- # ProcessCmd -> Initial transition occurs in generate_page_full
- $$data .= "<!--#" . $command . $char;
- return;
- }
-
- # Process the current input character
- if ($char eq '-') {
- # ProcessCmd -> ProcCmdDash
- $dash_count++;
- } else {
- # ProcessCmd -> ProcessCmd
- $command .= $char;
- }
-
- # Read rest of command string, then process command
- while ($char = getc($template)) {
- if ($char eq '-') {
- # ProcessCmd -> ProcCmdDash / ProcCmdDash -> ProcCmdCT
- $dash_count++;
- } elsif ($dash_count == 2 && $char eq '>') {
- # Run command (ProcCmdCT -> Initial transition occurs
- # in generate_page_full)
- if ($keyword eq "include") {
- $filepath = process_include_command($command,
- $data, $docroot, $path);
- } elsif ($keyword eq "fsize") {
- $filepath = process_fsize_command($command,
- $data, $docroot, $path);
- } elsif ($keyword eq "flastmod") {
- $filepath = process_flastmod_command($command,
- $data, $docroot, $path);
- }
-
- $$cacheentry{dependencies}{$filepath}{last_modified} =
- (stat($filepath))[9];
- push(@{$$cacheentry{dependencies}{$filepath}{commands}},
- { command => $keyword,
- start_offset => $start_offset,
- end_offset => tell($template)
- });
- return;
- } else {
- # ProcessCmd / ProcCmdDash / ProcCmdCT -> ProcessCmd
- while ($dash_count > 0) {
- $command .= "-";
- $dash_count--;
- }
- $command .= $char;
- }
- }
-}
-
-# Fully generate a page.
-# This involves parsing the page source looking for SSI commands.
-#
-# \param docroot The document root
-# \param path Path of the current document relative to ::docroot
-#
-sub generate_page_full
-{
- my ($docroot, $path) = @_;
- my $data = "";
- my $in_tag = 0;
- my $had_pling = 0;
- my $dash_count = 0;
- my $in_comment = 0;
- my $had_hash = 0;
- my $command = "";
- my $start_offset = 0;
-
- if (! -e $docroot . $path) {
- # File doesn't exist
- $cache{$docroot . $path}{data} = $data;
- $cache{$docroot . $path}{data_digest} =
- '"' . md5_base64($data) . '"';
- $cache{$docroot . $path}{data_last_modified} = time;
- return;
- }
-
- open my $template, $docroot . $path;
-
- # Save document modification time into cache
- my $lastmod = (stat($docroot . $path))[9];
- $cache{$docroot . $path} = { last_modified => $lastmod };
- my $cacheentry = $cache{$docroot . $path};
-
- # Parse document template, looking for SSI comments
- #
- # This is basically a state machine, thus:
- #
- # State: Input: Next state: Output:
- #
- # Initial [^<] Initial Input character
- # Initial '<' InTag None
- #
- # InTag [^!] Initial '<' followed by input
- # InTag ! InTagPling None
- #
- # InTagPling [^-] Initial '<!' followed by input
- # InTagPling '-' InTagPling1 None
- #
- # InTagPling1 [^-] Initial '<!-' followed by input
- # InTagPling1 '-' InComment None
- #
- # InComment [^#] Initial '<!--' followed by input
- # InComment '#' InCommentHash None
- #
- # InCommentHash [^a-zA-Z] ProcessCmd None
- # InCommentHash [a-zA-Z] InCommentHash None [1]
- #
- # ProcessCmd n/a Initial '<!--#' followed by the
- # command read in
- # InCommentHash followed
- # by input [2]
- # ProcessCmd [^-] ProcessCmd None
- # ProcessCmd '-' ProcCmdDash None
- #
- # ProcCmdDash [^-] ProcessCmd None [3]
- # ProcCmdDash '-' ProcCmdCT None
- #
- # ProcCmdCT [^>] ProcessCmd None [4]
- # ProcCmdCT '>' Initial Command specific [5]
- #
- # Notes:
- #
- # 1. This transition causes the input to be buffered as a command string
- # 2. This transition only happens if the command read so far is not
- # recognised
- # 3. A dash is appended to the command string, however
- # 4. A '>' is appended to the command string, however
- # 5. The output is determined by running the command.
- #
- while (defined(my $char = getc($template))) {
- if (!$in_comment && !$in_tag && $char eq '<') {
- # Initial -> InTag
- $start_offset = tell($template);
- $in_tag = 1;
- } elsif ($in_tag) {
- if (!$had_pling) {
- if ($char ne '!') {
- # InTag -> Initial
- $data .= "<" . $char;
- $in_tag = 0;
- } elsif ($char eq '!') {
- # InTag -> InTagPling
- $had_pling = 1;
- }
- } else {
- if ($char ne '-') {
- # InTagPling(1) -> Initial
- $data .= "<!";
- while ($dash_count > 0) {
- $data .= "-";
- $dash_count--;
- }
- $data .= $char;
-
- $had_pling = 0;
- $in_tag = 0;
- } else {
- # InTagPling -> InTagPling1
- $dash_count++;
-
- if ($dash_count == 2) {
- # InTagPling1 -> InComment
- $dash_count = 0;
- $in_comment = 1;
- $had_pling = 0;
- $in_tag = 0;
- }
- }
- }
- } elsif ($in_comment) {
- if (!$had_hash) {
- if ($char ne '#') {
- # InComment -> Initial
- $data .= "<!--" . $char;
- $in_comment = 0;
- } else {
- # InComment -> InCommentHash
- $command = "";
- $had_hash = 1;
- }
- } else {
- my $c = lc($char);
-
- if ('a' le $c && $c le 'z') {
- # InCommentHash -> InCommentHash
- $command .= $char;
- } else {
- # InCommentHash -> ProcessCmd
- process_command($template, $char,
- $command, \$data, $docroot,
- $path, $start_offset,
- $cacheentry);
-
- # ProcessCmd/ProcCmdCT -> Initial
- $had_hash = 0;
- $in_comment = 0;
- }
- }
- } else {
- # Initial -> Initial
- $data .= $char;
- }
- }
-
- close $template;
-
- # Save generated page data in cache
- $$cacheentry{data} = $data;
- $$cacheentry{data_digest} = '"' . md5_base64($data) . '"';
- $$cacheentry{data_last_modified} = time;
-}
-
-# Partially generate a page.
-# This involves using cached information to inject SSI data into a page
-#
-# \param docroot The document root
-# \param path The path of the current document, relative to ::docroot
-sub generate_page_partial
-{
- my ($docroot, $path) = @_;
-
- if (! -e $docroot . $path) {
- # File doesn't exist
- $cache{$docroot . $path}{data} = "";
- $cache{$docroot . $path}{data_digest} =
- '"' . md5_base64("") . '"';
- $cache{$docroot . $path}{data_last_modified} = time;
- return;
- }
-
- # Get dependency hash
- my $deps = $cache{$docroot . $path}{dependencies};
-
- # Build command map for this page
- my %cmds;
- foreach my $dep (keys %{$deps}) {
- my $index = 0;
- foreach my $cmd (@{$$deps{$dep}{commands}}) {
- # The key here is the index into the commands array
- # prepended to the dependency URL. This ensures that
- # we have unique map entries for each command.
- $cmds{$index . $dep} = $cmd;
- $index++;
- }
- }
-
- # Sort command map by start_offset
- my @sorted =
- sort { # Unpack dependency URLs and command array indices
- my ($a_index, $a_dep) = ($a =~ m/([0-9]+)(.*)/);
- my ($b_index, $b_dep) = ($b =~ m/([0-9]+)(.*)/);
- # Now compare the start offsets
- $$deps{$a_dep}{commands}[$a_index]{start_offset} <=>
- $$deps{$b_dep}{commands}[$b_index]{start_offset}
- }
- keys %cmds;
-
- my $data = "";
- my $temp;
- my $curpos = 0;
- my $template_length = 0;
-
- # Open requested document
- open TEMPLATE, $docroot . $path;
-
- # Find its length
- seek(TEMPLATE, 0, 2);
- $template_length = tell(TEMPLATE);
- seek(TEMPLATE, 0, 0);
-
- # Iterate through commands, loading intervening chunks of template
- foreach my $cmd (@sorted) {
- # Unpack dependency URL and command array index
- my ($index, $dep) = ($cmd =~ m/([0-9]+)(.*)/);
- my $vars = $$deps{$dep};
- my $length =
- $$vars{commands}[$index]{start_offset} - $curpos - 1;
-
- # Update last_modified time of this dependency (at least one
- # must have changed for a partial regeneration to occur)
- $$vars{last_modified} = (stat($dep))[9];
-
- # Read template input from end of previous dependency
- # to the start of this one
- read(TEMPLATE, $temp, $length);
-
- # Append it to our data buffer
- $data .= $temp;
-
- # Run this SSI command
- if ($$vars{commands}[$index]{command} eq "include") {
- do_include($dep, \$data);
- } elsif ($$vars{commands}[$index]{command} eq "fsize") {
- do_fsize($dep, \$data);
- } elsif ($$vars{commands}[$index]{command} eq "flastmod") {
- do_flastmod($dep, \$data);
- }
-
- # Skip over SSI command in template input
- $curpos = $$vars{commands}[$index]{end_offset};
-
- seek(TEMPLATE, $curpos, 0);
- }
-
- # Read any remaining template input
- read(TEMPLATE, $temp, $template_length - $curpos);
-
- $data .= $temp;
-
- close TEMPLATE;
-
- # Update document cache
- $cache{$docroot . $path}{data} = $data;
- $cache{$docroot . $path}{data_digest} = '"' . md5_base64($data) . '"';
- $cache{$docroot . $path}{data_last_modified} = time;
-}
-
-# Validate a cache entry
-#
-# \param docroot The document root
-# \param path The path of the current document, relative to ::docroot
-# \param entry Current cache entry or undef if none
-#
-sub validate_cache_entry
-{
- my ($docroot, $path, $entry) = @_;
-
- if (!$entry) {
- # No entry -- generate one
- generate_page_full($docroot, $path);
- return;
- }
-
- if ((stat($docroot . $path))[9] > $$entry{last_modified}) {
- # Page modified -- fully regenerate page
- generate_page_full($docroot, $path);
- return;
- }
-
- while (my ($dep, $data) = each(%{$entry->{dependencies}})) {
- if ((stat($dep))[9] > $$data{last_modified}) {
- # Dependency changed -- partially regenerate page
- generate_page_partial($docroot, $path);
- return;
- }
- }
-
- # Otherwise, the cached data is valid
-}
-