Plack-App-CGIBin-Streaming
view release on metacpan or search on metacpan
%ENV is populated
everything from the plack environment except keys starting with
"plack" or "psgi." is copied to %ENV.
"STDIN" and "STDOUT"
Both, "STDIN" and "STDOUT" are configured to use the
Plack::App::CGIBin::Streaming::IO PerlIO layer. On output, the layer
captures the data and sends it to the request object. Flushing via
$| is also supported. On input, the layer simply converts calls like
"readline STDIN" into a method call on the underlying object.
You can use PerlIO layers to turn the handles into UTF8 mode.
However, refrain from using a simple "binmode" to reverse the
effects of a prior "binmode STDOUT, ':utf8'". This won't pop the
Plack::App::CGIBin::Streaming::IO layer but neither will it turn off
UTF8 mode. This is considered a bug that I don't know how to fix.
(See also below)
Reading from "STDIN" using UTF8 mode is also supported.
Pitfalls and workarounds
SIGCHLD vs. SIGCLD
During the implementation I found a wierd bug. At least on Linux, perl
supports "CHLD" and "CLD" as name of the signal that is sent when a
child process exits. Also, when Perl calls a signal handler, it passes
the signal name as the first parameter. Now the question arises, which
name is passed when a child exits. As it happens the first assignment to
%SIG{CHLD} or $SIG{CLD} determines that name for the rest of the
lifetime of the process. Now, several plack server implementations, e.g.
Starman, rely on that name to be "CHLD".
As a workaround, "Plack::App::CGIBin::Streaming" contains this code:
BEGIN {
local $SIG{CHLD}=$SIG{CHLD};
}
If your server dies when it receives a SIGCHLD, perhaps the module is
loaded too late.
binmode
Sometimes one needs to switch STDOUT into UTF8 mode and back. Especially
the *back* is problematic because the way it is done is often simply
"binmode STDOUT". Currently, this won't revert the effect of a previous
"binmode STDOUT, ':utf8'".
Instead use:
binmode STDOUT, ':bytes';
EXAMPLE
This distribution contains a complete example in the eg/ directory.
After building the module by
perl Build.PL
./Build
you can try it out:
(cd eg && starman -l :5091 --workers=2 --preload-app app.psgi) &
Then you should be able to access
* <http://localhost:5091/clock.cgi?30>
* <http://localhost:5091/flush.cgi>
The clock example is basically the script displayed above. It works in
Firefox. Other browsers don't support multipart HTTP messages.
The flush example demonstrates filtering. It has been tested wich
Chromium 35 on Linux. The script first prints a part of the page that
contains the HTML comment "<!-- FlushHead -->". The filter recognizes
this token and pushes the page out. You should see a red background and
the string "loading -- please wait". After 2 seconds the page should
turn green and the string should change to "loaded".
All of this very much depends on browser behavior. The intent is not to
provide an example that works for all of them. Instead, the capabilities
of this module are shown. You can also test these links with "curl"
instead.
The example PSGI file also configures an access_log and an error_log.
AUTHOR
Torsten Förtsch <torsten.foertsch@gmx.net>
COPYRIGHT
Copyright 2014 Binary.com
LICENSE
This program is free software; you can redistribute it and/or modify it
under the terms of the the Artistic License (2.0). A copy of the full
license is provided by the LICENSE file in this distribution and can be
obtained at
<http://www.perlfoundation.org/artistic_license_2_0>
SEE ALSO
* Plack::App::CGIBin
* CGI::Compile
* Plack::App::CGIBin::Streaming::Request
* Plack::App::CGIBin::Streaming::IO
( run in 1.494 second using v1.01-cache-2.11-cpan-e93a5daba3e )