FastCGI interface (PLP::CGI extension using FCGI)
authorMischa POSLAWSKY <perl@shiar.org>
Tue, 2 Oct 2007 10:23:27 +0000 (12:23 +0200)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 17 Mar 2008 19:42:36 +0000 (20:42 +0100)
Do not exit from PLP::CGI, allowing it to be used consecutively.

Coincidentally, PLP::FastCGI does just that: extending the PLP::CGI
interface to handle FCGI requests. Its import() runs a PLP dispatcher,
so a FastCGI executable (example plp.fcgi is provided) only has to
C<use PLP::FastCGI>. If a server supports run arguments, a wrapper
script isn't even needed this way: just do /usr/bin/perl -MPLP::FastCGI.

PATH_TRANSLATED is explicitly removed from environment so file names are
gotten from SCRIPT_*, which mostly already point to the requested script
(at least much more correctly than can be determined from PATH_*).

This seems to work correctly on at least:
- Apache 1.3.34, 2.2.4, 2.2.8 with mod_fastcgi and mod_fcgid
- Lighttpd 1.4.7 and 1.4.18 with mod_fastcgi

Caching can be controlled by setting an environment variable PLP_CACHE
(unlike with mod_perl, no other means of configuration are provided).
If not specified, PLPcache will be turned on.

fcgi script

PLP/CGI.pm
PLP/FastCGI.pm [new file with mode: 0644]
plp.fcgi [new file with mode: 0755]

index 56ca4db72eece75fcd434f6ed04211545ee4bc4d..817a5523dd4af806dd829e4750210e61e1f70b05 100644 (file)
@@ -2,7 +2,7 @@ package PLP::CGI;
 
 use strict;
 
-our $VERSION = '1.01';
+our $VERSION = '1.02';
 
 use PLP;
 
@@ -21,7 +21,7 @@ sub init {
                        if (not $path =~ s/(\/+[^\/]*)$//) {
                                printf STDERR "PLP: Not found: $path$path_info ($ENV{REQUEST_URI})\n";
                                PLP::error(undef, 404);
-                               exit;
+                               return;
                        }
                        # move last path element onto PATH_INFO
                        $path_info = $1 . $path_info;
@@ -44,7 +44,7 @@ sub init {
        if (not -r $ENV{PLP_FILENAME}) {
                print STDERR "PLP: Can't read: $ENV{PLP_FILENAME} ($ENV{REQUEST_URI})\n";
                PLP::error(undef, 403);
-               exit;
+               return;
        }
 
        delete @ENV{
@@ -56,6 +56,7 @@ sub init {
        chdir $dir;
 
        $PLP::code = PLP::source($file, 0, undef, $ENV{PLP_FILENAME});
+       return 1;
 }
 
 sub read ($) {
@@ -67,8 +68,7 @@ sub read ($) {
 # This is run by the CGI script. (#!perl \n use PLP::CGI; PLP::CGI::everything;)
 sub everything {
        PLP::clean();
-       init();
-       PLP::start();
+       $_[0]->init() and PLP::start();
 }
 
 1;
diff --git a/PLP/FastCGI.pm b/PLP/FastCGI.pm
new file mode 100644 (file)
index 0000000..e16fbcb
--- /dev/null
@@ -0,0 +1,22 @@
+package PLP::FastCGI;
+
+use strict;
+
+use PLP::CGI;
+use FCGI;
+use base 'PLP::CGI';
+
+our $VERSION = '1.00';
+
+sub import {
+       my $self = shift;
+       my $request = FCGI::Request();
+       while ($request->Accept() >= 0) {
+               $PLP::use_cache = !defined $ENV{PLP_CACHE} || $ENV{PLP_CACHE}; # before it's clean()ed
+               delete $ENV{PATH_TRANSLATED};
+               $self->everything();
+       }
+}
+
+1;
+
diff --git a/plp.fcgi b/plp.fcgi
new file mode 100755 (executable)
index 0000000..372459e
--- /dev/null
+++ b/plp.fcgi
@@ -0,0 +1,7 @@
+#!/usr/bin/env perl
+
+# This is a dispatch script for FastCGI installations.
+# It is not needed with normal CGI or mod_perl.
+
+use PLP::FastCGI;
+