17. > grep ‘(CGI.pm|ENV)’ lib/MT/App.pm
if ( my $path_info = $ENV{PATH_INFO} ) {
# defined which interferes with CGI.pm determining the
delete $ENV{PATH_INFO};
# CGI.pm has this terrible flaw in that if a POST is in effect,
my $query_string = $ENV{'QUERY_STRING'}
if defined $ENV{'QUERY_STRING'};
$query_string ||= $ENV{'REDIRECT_QUERY_STRING'}
if defined $ENV{'REDIRECT_QUERY_STRING'};
my $len = $ENV{CONTENT_LENGTH} || 0;
return $ENV{ 'HTTP_' . $key };
$app->{request_method} = $ENV{REQUEST_METHOD} || '';
## Older versions of CGI.pm didn't have an 'upload' method.
if ( my $host = $ENV{HTTP_HOST} ) {
: $ENV{REMOTE_ADDR});
$cwd = $ENV{DOCUMENT_ROOT} || $app->mt_dir;
58. my $app = sub {
my $env = shift;
return [ $status, $header, $body ];
};
my $mw = sub {
my $env = shift;
# do something with $env
my $res = $app->($env);
# do something with $res;
return $res;
};
64. use Plack::Test;
use HTTP::Request::Common;
my $app = sub {
my $env = shift;
return [ $status, $header, $body ];
};
test_psgi app => $app, client => sub {
my $cb = shift;
my $req = GET “http://localhost/foo”;
my $res = $cb->($req);
# test $res;
};
65. use Plack::Test;
use HTTP::Request::Common;
$Plack::Test::Impl = “Server”;
my $app = sub {
my $env = shift;
return [ $status, $header, $body ];
};
test_psgi app => $app, client => sub {
my $cb = shift;
my $req = GET “http://localhost/foo”;
my $res = $cb->($req);
# test $res;
};
67. use IO::Handle::Util qw(io_from_getline);
my $app = sub {
my $env = shift;
my $io = io_from_getline sub {
return $chunk; # undef when done
};
return [ $status, $header, $io ];
};
68. use IO::Writer; # TBD: API might change
use AnyEvent::Timer;
my $app = sub {
my $env = shift;
my $io = writer {
my $h = shift;
my $t; $t = AE::timer 0, 1, sub {
$t;
$h->push_write($stuff);
};
};
return [ $status, $header, $io ];
};
77. Summary
• PSGI is an interface, Plack is the code.
• We have many (pretty fast) servers.
• We have adapters and tools for most web
frameworks.
• Use it!