NAME

Dancer::Plugin::FakeCGI - run CGI methods or Perl-files under Dancer

SYNOPSIS

DESCRIPTION

Supports to run CGI perl files on CGI methods under Dancer.

CONFIGURATION

plugins:
   FakeCGI:
      cgi-dir: 'cgi-dir'
      cgi-bin: '/cgi-bin'
      cgi-package: 'lib/CGI'
      cgi-class: ourCGI
      stdout-type: "file"
      temp-dir: "tmp"
cgi-dir - for setting directory where is placed Perl CGI file, standart is 'cgi-dir'. This directory must be in root on Dancer directory.
cgi-bin - web url directory where are Perl CGI files visible. Must be set.
cgi-package - for setting INC library where is CGI packagesa(loaded from fake_cgi_method), standart is nothing.
cgi-class - definition child-classes for CGI, it can be defined as ARRAY, standart every 'CGI*::'
stdout-type - where will be saved captured string from STD[OUT|ERR], standart is capture into memory. Change with this options:
file - captured string will be saved in directory defined temp-dir and in after hook will be avery temp file removed
memory - for saving captured string use IO::Scalar
temp-dir - temporary directory where will be save all captured files if stdout-type is set to file. Best option is use file captured and temp-dir mount as RAM filesystem

TODO

1 - Maybe captured string parsed in HTTP::Message->parse
2 - CGI::Push use infinity loop which not existed than we don't capture any string from STDOUT and doesn't send any data.
3 - script_name() with referer
4 - Mod_PERL emulation for version 2
5 - find better solution for capturing STD[OUT|ERR] under system() call when capture to memory used
6 - Performance issue :

every CGI files are loaded(served) 20-50% slowest then under Mod_PERL(Registry.pm). This emulation get about 15-20ms more than uner Apache. Next difference is capture in memory and to file. In memory is 10-20% faster. One problem finded and there is Cwd::cwd() function which is slowest than getcwd() and take 65ms. CGI::Compile() is similar as Mod_PERL::PerlRun(). Everytime it run eval() on given loaded code. If we want to use behavior as Apache::Registry(), than should on first time evaled of given code to memory as package with function and other every call run this method to omited evaled code into memory.

BUGS

1 - Not use infinity loop!!! Every CGI script must exited - finished to run properly in Dancer
2 -Problem with fork|system function under HTTP::Server::Simple. This server make bad opening file descriptor of STDOUT. On this server it will be redirected to STDERR

METHODS

<$capture> - is reference to this HASH

STDOUT|STDERR - type of captured string for given output. It is HASH reference to this other options:
string - if setting enabled capturing to memory this is string contains every characters captured
io_fh - handler to IO::File if is set to capturing into file, if is set to memory it is handler to IO::Scalar
filename - filename with path if capturing is to file
header_len - this is size of HTTP header. On this position start HTML content. It is only for capturing into file
std_fh - saved original filehandler into this param if is capturing enabled. If capturing stop than this option not exist

PARAMS for _run_code() is hashref

capture_stderr - STDERR will be captured similar as STDOUT and when eval(_run_code) finished, that will be loged
timeout - in seconds which can timeouted given eval via alarm() function. If is 0|undefined - disabled it
ret_error - try run given code and return after eval

fake_cgi_bin_url($name[,@other])

Method which return url for given $name. If set @other, than this will be append to given URL with separattor /

fake_cgi_method($package, $method, $params, @args)

Method for runned specified CGI method-function and return values of runned function.

$package - Package name where is method, which we run. Automatically load this package to memory in first run.
$method - Method name which we run.
$params - Hash ref of params, look of params to _run_code()
@args - Arguments for given method

fake_cgi_file($file, $params, $test_is_perl)

Method for runned specified Perl CGI file and returned exit value

$file - CGI filename and first in first run we compiled this file into memory
$params - Hash ref of params, look of params to _run_code()
$test_is_perl - try first if given file is Perl code, default we use given filename as is Perl script.

fake_cgi_compile(@args)

Load packages into memory or Compiled files into memory. @args is array of this HASHREF options:

package - load package into memory
filename - compile Perl filename into memory
test_is_perl - if filename than run test if it is Perl CGI file

fake_cgi_is_perl($file, $compile)

Tries to figure out whether the CGI is Perl code or not.

Return 1 if its Perl code otherwise is 0.

$file - filename of test file
$compile - if true and given tested file is Perl code, than compiled given file into memory

fake_cgi_bin($code, $patterns, $test_is_perl)

Automatically serve CGI files from cgi-dir directory

plugins:
   FakeCGI:
      cgi-bin_file_pattern: *.cgi

Setting cgi-bin_file_pattern can be defined as array is pattern of file or files, which will be readed and try to compiled and setted to run as CGI.

$code - reference for code, if not set, than automatically add servering for given file with this options.

Given method should return true or false. If given code no return true, than serve given CGI files in standart way.

This is parametter for given called code:

directory
filename
url
is_perl
$paterns - is scalar or can be array ref. If not set, than will be set from settings, otherwise read everything which kind of file will be readed
$test_is_perl - test if readable file it is Perl CGI file, if not defined, than we use every file as Perl CGI.

EXAMPLES

Standart definition in setting file:
plugins:
   FakeCGI:
      cgi-bin_file_pattern: "*.pl"

In yours Dancer package only put fake_cgi_bin(); and this script try to load every *.pl files in cgi-bin directory under Dancer directory.

Tested files in own function for every *.pl and *.sh file:
sub test_file	{
    my ($cgi_bin, $cgi, $url, $is_perl) = @_;

    return 1 if ($cgi =~ /^\./);     # skip serving this file 
    return 1 if ($cgi =~ /test.pl/); # skip serving this file  

    if ($cgi eq "index.pl") {  # own serving for given file
        any $url => sub {
            redirect "/index.sh";
        };
        return 1;
    }

    return 0; # default server
}

fake_cgi_bin(\&test_file, ["*.pl", "*.sh"], 1);

fake_cgi_as_string($ret_ref)

Return captured strings from CGI, which will be printed to STDOUT.

If $ret_ref than given string will be returned as reference to SCALAR. This option can make better performance.

fake_cgi_capture($capture_start)

This method every time return actuall settings form capture method.

If argument $capture_start is defined, can be possible START or STOP capturing with this options:

true|1 - capturing will be initalized or restarted. Every data in restarting will bi appended.
false|0 - capturing

RETURN array of this position:

Hash reference for $capture
IO::Scalar or IO::File of captured STDOUT strings
actual position of seek() - tell() method
size of all data captured from STDOUT in bytes
len of HTTP header. From this position start HTML content

HOOKS

This plugin uses Dancer's hooks support to allow you to register code that should execute at given times.

TYPES

fake_cgi_before($env,$capture) : hook which will be called before run CGI method or Perl CGI file. Arguments is HASH reference to %ENV and reference to $capture
fake_cgi_after($capture) : hook which will be called after runned CGI method or Perl CGI file. Arguments is reference to $capture

EXAMPLE

hook 'fake_cgi_before' => sub {
    my ($env,$capture) = @_;
};

hook 'fake_cgi_after' => sub {
    my ($capture) = @_;
};

AUTHOR

Igor Bujna, <igor.bujna@post.cz>

CONTRIBUTING

ACKNOWLEDGEMENTS

For every developers of this packages, when made good ideas for this code :

Catalyst::Controller::CGIBin, HTTP::Request::AsCGI, CGI::PSGI, CGI::Emulate::PSGI

SUPPORT

LICENSE AND COPYRIGHT

Copyright 2010-2013 Igor Bujna.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

SEE ALSO

Dancer

IO::Scalar

CGI::Compile

Test::TinyMocker

HTTP::Message