Dancer-Plugin-FakeCGI
view release on metacpan or search on metacpan
lib/Dancer/Plugin/FakeCGI.pm view on Meta::CPAN
my ($ret, $err) = (undef, undef);
{
_capture_start(1, (!$params->{ret_error} && $params->{capture_stderr}) ? 1 : 0);
debug("After _capture_start() ");
Dancer::Factory::Hook->instance->execute_hooks('fake_cgi_before', \%ENV, $capture) unless ($params->{ret_error});
debug("After hook: fake_cgi_before ");
# Change to current dir where is cgi-bin
#my $currWorkDir = Cwd::cwd(); # calling method cwd() is slowest than getcwd and use about 65ms
my $currWorkDir = Cwd::getcwd();
debug("After Cwd...");
my $dir = _ret_cgi_bin_path();
chdir($dir);
debug("Before eval given code() ");
#make sure this hooks are restored to their original state
local $SIG{__DIE__} = $SIG{__DIE__};
local $SIG{__WARN__} = $SIG{__WARN__};
# CGI::Compile made it
## Change script name
#my $old_name = $0;
##local $0 = $filename; #this core dumps!?
#*0 = \$filename if ($filename);
$run_code_evaled = 1;
# Test for timeout
local $SIG{ALRM} = $SIG{ALRM};
my $timeout = _parse_int($params->{timeout});
if ($timeout) {
$SIG{ALRM} = sub { die $str_alarmed };
alarm $timeout;
}
eval { # Run compiled code
no strict 'refs';
$ret = &{$code}();
};
alarm(0) if ($timeout);
$err = $@; # Save error to scalar
#*0 = $old_name;
$run_code_evaled = 0;
chdir($currWorkDir);
debug("After eval given code() ");
_capture_end();
debug("After _capture_end() ");
}
return $err if ($params->{ret_error});
# When is in CGI called system() function, there is problem with filehandle and it is a blocked, then try to reopen it
sub _reopen_file {
return unless ($_[0]);
close($_[0]) or warn "Can't close IO handler";
open(my $fh, "<:utf8", $_[0]) or die "Can't reopen for reading : $!";
return $fh;
}
# Print captured string on STDERR
if ($capture->{"STDERR"}->{string}) {
debug $capture->{"STDERR"}->{string};
} elsif ($capture->{"STDERR"}->{io_fh}) {
#$capture->{io_err} = _reopen_file($capture->{io_err});
seek($capture->{"STDERR"}->{"io_fh"}, 0, SEEK_SET);
# Print everything in STDERR as one line
debug $capture->{"STDERR"}->{"io_fh"}->getlines();
unlink($capture->{"STDERR"}->{"filename"}) if ($capture->{"STDERR"}->{"filename"});
}
delete($capture->{"STDERR"});
debug("After STDERR print ");
# Get on first position
if ($settings->{'stdout-type'} eq 'file') {
#$capture->{io_out} = _reopen_file($capture->{io_out});
} elsif (exists($capture->{"STDOUT"}) && $capture->{"STDOUT"}->{"io_fh"}) {
seek($capture->{"STDOUT"}->{"io_fh"}, 0, SEEK_SET);
}
# If error captured, than we finish
if ($err) {
croak $err eq $str_alarmed
? "Timeouted after " . $params->{timeout} . " seconds"
: $err;
return;
}
# Delete headers from captured STDOUT
if (exists($capture->{"STDOUT"}) && $capture->{"STDOUT"}->{"io_fh"}) {
my $r_str = undef;
my $str_len = 0;
if ($capture->{"STDOUT"}->{"string"}) {
$r_str = \$capture->{"STDOUT"}->{"string"};
} else {
my $str = '';
$str_len = read($capture->{"STDOUT"}->{"io_fh"}, $str, 8 * 1024); # Read 8kB from file a find if it isn't header
$r_str = \$str;
}
# From HTTP::Message->parse
my @hdr;
while (1) {
unless ($r_str) {
last;
} elsif ($$r_str =~ s/^([^\s:]+)[ \t]*: ?(.*)\n?//) {
push(@hdr, $1, $2);
$hdr[-1] =~ s/\r\z//;
} elsif (@hdr && $$r_str =~ s/^([ \t].*)\n?//) {
$hdr[-1] .= "\n$1";
( run in 1.027 second using v1.01-cache-2.11-cpan-39bf76dae61 )