PSGI is a Perl port of Python's WSGI and Ruby's Rack that defines a common interface between web servers and frameworks. Plack provides reference implementations of PSGI servers as well as middleware and utilities. This allows frameworks to run on many servers like standalone, FastCGI, and Apache using a common PSGI application interface. Plack is fast, supports many frameworks through adapters, and provides tools like Plackup and middleware to help build and test PSGI applications.
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!