Net-Async-FastCGI

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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:

MANIFEST  view on Meta::CPAN

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

README  view on Meta::CPAN


      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.

t/40psgi.t  view on Meta::CPAN

      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 )