Plack-App-CGIBin-Streaming

 view release on metacpan or  search on metacpan

lib/Plack/App/CGIBin/Streaming.pm  view on Meta::CPAN

__END__

=encoding utf-8

=head1 NAME

Plack::App::CGIBin::Streaming - allow old style CGI applications to use
the plack streaming protocol

=head1 SYNOPSIS

in your F<app.psgi>:

 use Plack::App::CGIBin::Streaming;

 Plack::App::CGIBin::Streaming->new(root=>...)->to_app;

=head1 DESCRIPTION

With L<Plack> already comes L<Plack::App::CGIBin>.
C<Plack::App::CGIBin::Streaming> serves a very similar purpose.

So, why do I need another module? The reason is that L<Plack::App::CGIBin>
first collects all the output from your CGI scripts before it prints the
first byte to the client. This renders the following simple clock script
useless:

 use strict;
 use warnings;

 $|=0;

 my $boundary='The Final Frontier';
 print <<"EOF";
 Status: 200
 Content-Type: multipart/x-mixed-replace;boundary="$boundary";

 EOF

 $boundary="--$boundary\n";

 my $mpheader=<<'HEADER';
 Content-type: text/html; charset=UTF-8;

 HEADER

 for(1..100) {
     print ($boundary, $mpheader,
            '<html><body><h1>'.localtime()."</h1></body></html>\n");
     $|=1; $|=0;
     sleep 1;
 }

 print ($boundary);

Although multipart HTTP messages are quite exotic, there are situations
where you rather want to prevent this buffering. If your document is very
large for example, each instance of your plack server allocates the RAM
to buffer it. Also, you might perhaps send out the C<< <head> >> section
of your HTTP document as fast as possible to enable the browser load JS and
CSS while the plack server is still busy with producing the actual document.

C<Plack::App::CGIBin::Streaming> compiles the CGI scripts using
L<CGI::Compile> and provides a runtime environment similar to
C<Plack::App::CGIBin>. Compiled scripts are cached. For production
environments, it is possible to precompile and cache scripts at server
start time, see the C<preload> option below.

Every single request is represented as an object that inherits from
L<Plack::App::CGIBin::Streaming::Request>. This class mainly provides
means for handling response headers and body.

=head2 Options

The plack app is built as usual:

 $app=Plack::App::CGIBin::Streaming->new(@options)->to_app;

C<@options> is a list of key/value pairs configuring the app. The
C<Plack::App::CGIBin::Streaming> class inherits from L<Plack::App::File>.
So, everything recognized by this class is accepted. In particular, the
C<root> parameter is used to specify the directory where your CGI programs
reside.

Additionally, these parameters are accepted:

=over 4

=item request_class

specifies the class of the request object to construct for every request.
This class should implement the interface described in
L<Plack::App::CGIBin::Streaming::Request>. Best if your request class
inherits from L<Plack::App::CGIBin::Streaming::Request>.

This parameter is optional. By default
C<Plack::App::CGIBin::Streaming::Request> is used.

=item request_params

specifies a list of additional parameters to be passed to the request
constructor.

By default the request constructor is passed 2 parameters. This list is
appended to the parameter list like:

 $R = $class->new(
     env => $env,
     responder => $responder,
     @{$self->request_params//[]},
 );

=item preload

In a production environment, you probably want to use a (pre)forking server
to run the application. In this case is is sensible to compile as much
perl code as possible at server startup time by the parent process because
then all the children share the RAM pages where the code resides (by
copy-on-write) and you utilize your server resources much better.

One way to achieve that is to keep your CGI applications very slim and put



( run in 0.989 second using v1.01-cache-2.11-cpan-13bb782fe5a )