Net-Async-FastCGI
view release on metacpan or search on metacpan
Revision history for Net-Async-FastCGI
0.26 2024-07-29
[CHANGES]
* Added streaming stdin support
* General module style refresh:
+ use v5.14
+ Pod style updates
0.25 CHANGES:
* Import PSGI support from FCGI::Async directly here
* Add some convenience methods to get often-used fields from request
without needing to use ->param
0.24 CHANGES:
t/08request-shortwrites.t
t/09request-streamstdout.t
t/10request-close.t
t/11request-encoding.t
t/12request-unknown.t
t/13request-handles.t
t/14request-streamstdin.t
t/20get_values.t
t/30request-HTTP.t
t/40psgi.t
t/41psgi-streaming.t
t/99pod.t
t/lib/TestFCGI.pm
README
LICENSE
META.yml
META.json
CODE references for on_request event handler.
default_encoding => STRING
Sets the default encoding used by all new requests. If not supplied
then UTF-8 will apply.
stream_stdin => BOOL
If true, requests will expect to handling streaming of stdin data. In
this mode, the on_request event handler will be invoked once
parameters for a new request have been received, even if the stdin
stream is not yet complete.
METHODS
listen
$fcgi->listen( %args );
lib/Net/Async/FastCGI.pm view on Meta::CPAN
CODE references for C<on_request> event handler.
=item default_encoding => STRING
Sets the default encoding used by all new requests. If not supplied then
C<UTF-8> will apply.
=item stream_stdin => BOOL
If true, requests will expect to handling streaming of stdin data. In this
mode, the C<on_request> event handler will be invoked once parameters for a
new request have been received, even if the stdin stream is not yet complete.
=back
=cut
sub _init
{
my $self = shift;
lib/Net/Async/FastCGI/PSGI.pm view on Meta::CPAN
my %env = (
%{ $req->params },
'psgi.version' => [1,0],
'psgi.url_scheme' => ($req->param("HTTPS")||"off") =~ m/^(?:on|1)/i ? "https" : "http",
'psgi.input' => $req->stdin,
'psgi.errors' => $req->stderr,
'psgi.multithread' => 0,
'psgi.multiprocess' => 0,
'psgi.run_once' => 0,
'psgi.nonblocking' => 1,
'psgi.streaming' => 1,
# Extensions
'net.async.fastcgi' => $self,
'net.async.fastcgi.req' => $req,
'io.async.loop' => $self->get_loop,
);
my $resp = $self->{app}->( \%env );
my $responder = sub {
lib/Net/Async/FastCGI/Request.pm view on Meta::CPAN
$loop->add( $fcgi );
$loop->run;
=head1 DESCRIPTION
Instances of this object class represent individual requests received from the
webserver that are currently in-progress, and have not yet been completed.
When given to the controlling program, each request will already have its
parameters (and, on servers without stdin streaming enabled, its STDIN data).
The program can then write response data to the STDOUT stream, messages to the
STDERR stream, and eventually finish it.
This module would not be used directly by a program using
C<Net::Async::FastCGI>, but rather, objects in this class are passed into the
C<on_request> event of the containing C<Net::Async::FastCGI> object.
=cut
sub new
lib/Net/Async/FastCGI/Request.pm view on Meta::CPAN
line of data is available then it is returned, including the linefeed, and
removed from the buffer. If not, then any remaining partial line is returned
and removed from the buffer. If no data is available any more, then C<undef>
is returned instead.
=cut
sub read_stdin_line
{
my $self = shift;
croak "Cannot call ->read_stdin_line on streaming-stdin requests" if $self->{stream_stdin};
my $codec = $self->{codec};
if( $self->{stdin} =~ s/^(.*[\r\n])// ) {
return $codec ? $codec->decode( $1 ) : $1;
}
elsif( $self->{stdin} =~ s/^(.+)// ) {
return $codec ? $codec->decode( $1 ) : $1;
}
else {
lib/Net/Async/FastCGI/Request.pm view on Meta::CPAN
This method works similarly to the C<read(HANDLE)> function. It returns the
next block of up to $size bytes from the STDIN buffer. If no data is available
any more, then C<undef> is returned instead. If $size is not defined, then it
will return all the available data.
=cut
sub read_stdin
{
my $self = shift;
croak "Cannot call ->read_stdin on streaming-stdin requests" if $self->{stream_stdin};
my ( $size ) = @_;
return undef unless length $self->{stdin};
$size = length $self->{stdin} unless defined $size;
my $codec = $self->{codec};
# If $size is too big, substr() will cope
my $bytes = substr( $self->{stdin}, 0, $size, "" );
lib/Net/Async/FastCGI/Request.pm view on Meta::CPAN
}
=head2 set_on_stdin_read
$req->set_on_stdin_read( $on_stdin_read );
$again = $on_stdin_read->( $req, $buffref, $eof );
I<Since version 0.26.>
Only valid on requests on servers with stdin streaming enabled.
This method should be called as part of the C<on_request> event on the server,
to set the callback function to invoke when new data is provided to the stdin
stream for this request.
The callback function is invoked in a similar style to the C<on_read> event
handler of an L<IO::Async::Stream>. It is passed the request itself, along
with a SCALAR reference to the buffer containing the stdin data, and a boolean
indicating if the end of stdin data has been reached.
It should inspect this buffer and remove some prefix of it that it wishes to
consume. Any remaining content will be present on the next call. If it returns
a true value, the callback will be invoked again immediately, to consume more
data. This continues until there is no more data left, or it returns false.
=cut
sub set_on_stdin_read
{
my $self = shift;
croak "Cannot call ->set_on_stdin_read except on streaming-stdin requests" unless $self->{stream_stdin};
( $self->{on_stdin_read} ) = @_;
}
sub _print_stream
{
my $self = shift;
my ( $data, $stream ) = @_;
while( length $data ) {
# Send chunks of up to MAXRECORDDATA bytes at once
lib/Net/Async/FastCGI/Request.pm view on Meta::CPAN
$self->{used_stderr} = 1;
$self->{stderr} .= $codec ? $codec->encode( $data ) : $data;
$self->{conn}->_req_needs_flush( $self );
}
=head2 stream_stdout_then_finish
$req->stream_stdout_then_finish( $readfn, $exitcode );
This method installs a callback for streaming data to the STDOUT stream.
Whenever the output stream is otherwise-idle, the function will be called to
generate some more data to output. When this function returns C<undef> it
indicates the end of the stream, and the request will be finished with the
given exit code.
If this method is used, then care should be taken to ensure that the number of
bytes written to the server matches the number that was claimed in the
C<Content-Length>, if such was provided. This logic should be performed by the
containing application; C<Net::Async::FastCGI> will not track it.
SCRIPT_NAME => "",
SERVER_NAME => "localhost",
SERVER_PORT => "80",
SERVER_PROTOCOL => "HTTP/1.1",
'psgi.version' => [1,0],
'psgi.url_scheme' => "http",
'psgi.run_once' => 0,
'psgi.multiprocess' => 0,
'psgi.multithread' => 0,
'psgi.streaming' => 1,
'psgi.nonblocking' => 1,
},
'received $env in PSGI app' );
my $CRLF = "\x0d\x0a";
my $expect_stdout = join( "", map "$_$CRLF",
"Status: 200",
"Content-Type: text/plain",
'' ) .
"Hello, world";
( run in 0.294 second using v1.01-cache-2.11-cpan-4d50c553e7e )