App-FastishCGI
view release on metacpan or search on metacpan
lib/App/FastishCGI.pm view on Meta::CPAN
my ( $wtr, $rdr, $err );
my $pid;
eval { $pid = IPC::Open3::open3( $wtr, $rdr, $err, $script_filename ); };
if ($@) {
$self->html_error( $req, "$script_filename: Failed to open script: $@" );
return;
}
if ( !$pid ) {
$self->html_error( $req, "$script_filename: Failed to open script: $!" );
return;
}
if ( ( $req->param('REQUEST_METHOD') eq 'POST' ) && ( $req->param('CONTENT_LENGTH') + 0 > 0 ) )
{
my $req_len = 0 + $req->param('CONTENT_LENGTH');
$self->log_debug("[$rid] Request length $req_len");
my $post_data = $req->read_stdin($req_len);
$self->log_debug("[$rid] POST data $post_data");
$wtr->print($post_data);
}
$self->{requests}->{$rid}->{handle} = AnyEvent::Handle->new(
fh => $rdr,
on_read => sub {
$self->{requests}->{$rid}->{buffer} .= $_[0]->rbuf;
$_[0]->rbuf = '';
},
on_eof => sub {
undef $self->{requests}->{$rid}->{handle};
},
);
$self->{requests}->{$rid}->{child} = AnyEvent->child(
pid => $pid,
cb => sub {
my ( $pid, $return_val ) = @_;
my $status = $return_val >> 8;
# XXX the cgi spec, as far as I have found, is like shell scripting in
# that scripts should return 0 on success. However some of the scripts I
# need to use return 1 instead.
if ( $status != 0 && $status != 1 ) {
$self->html_error(
$req,
"Script $script_filename exited abnormally, with status: $status",
$self->{requests}->{$rid}->{buffer}
);
} else {
$self->log_debug("[$rid] Script $script_filename completed");
$req->print_stdout( $self->{requests}->{$rid}->{buffer} );
$req->finish;
}
$self->clear_request($rid);
},
);
$self->{requests}->{$rid}->{timer} = AnyEvent->timer(
after => $self->{timeout},
cb => sub {
$self->html_error( $req, "Script '$script_filename' exceeded timeout value" );
$self->clear_request($rid);
}
);
$self->log_debug("[$rid] setup");
$self->show_active_requests if $self->{debug};
return;
}
sub new {
my $this = shift;
my $class = ref($this) || $this;
my %opt = ( ref $_[0] eq 'HASH' ) ? %{ $_[0] } : @_;
my $self = bless \%opt, $class;
$self->log_debug( Dumper($self) ) if $self->{debug};
$self->_init;
return $self;
}
sub _init {
my $self = shift;
$self->set_signal_handlers;
openlog( 'fastishcgi', "ndelay,pid", 'user' );
# stylesheet is a url or path for web server. If none is supplied add default
if ( $self->{css} ) {
$self->{css} = sprintf '<link href="%s" rel="stylesheet" type="text/css">', $self->{css};
} else {
$self->{css} = <<CSS;
<style type="text/css">
pre { background-color: white; padding: 1em; border: 2px solid orange; color: black; }
body {color: black; background-color: grey; }
.err_msg {color: black; background-color: orange; }
</style>
CSS
}
$self->{requests_total} = 0;
$self->{requests} = {};
}
sub main_loop {
my $self = shift;
my $fcgi;
# TODO IO::Socket::INET6
if ( defined $self->{socket} ) {
$self->log_info( sprintf 'Listening on UNIX socket: %s', $self->{socket} );
$fcgi = AnyEvent::FCGI->new(
socket => $self->{socket},
( run in 0.492 second using v1.01-cache-2.11-cpan-bbcb1afb8fc )