SlideShare a Scribd company logo
1 of 323
Download to read offline
Plack Basics
Leo Lapworth @ YAPC::EU 2011




  Much content from Tatsuhiko Miyagawa’s
          YAPC::NA 2010 talk
What is Plack?
What is Plack?

“Superglue for Perl 5 Web
  Frameworks and Web
        Servers”
How will that help me?
How will that help me?
‣ Flexibility
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
‣ Development
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
‣ Development
‣ Testing
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
‣ Development
‣ Testing
‣ Deployment
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
‣ Development
‣ Testing
‣ Deployment
‣ World peace
How will that help me?
‣ Flexibility
‣ Middleware (plugins)
‣ Apps
‣ Development
‣ Testing
‣ Deployment
‣ World peace
History...
Hello World
#!/usr/bin/perl
use strict;

print “Content-Type: text/plainrnrn”;
print “Hello World”;
package HelloWorld;
use strict;
use Apache::RequestRec;
use Apache::RequestIO;
use Apache::Const -compile => qw(OK);

sub handler {
  my $r = shift;

     $r->content_type(‘text/plain’);
     $r->print(“Hello World”);

     return Apache::Const::OK;
}

1;
use FCGI;

my $req = FCGI::Request();

while ($req->Accept >= 0) {

    print “Content-Type: text/plainrnrn”;
    print “Hello World”;

}
package HelloWorld;
use base qw(HTTP::Server::Simple::CGI);

sub handle_request {
  my($self, $cgi) = @_;

     print “HTTP/1.0 200 OKrn”;
     print “Content-Type: text/plainrnrn”;
     print “Hello World”;
}

1;
All similar
but slightly different
Painful to support
  all of them 
There was
one common way
 to do all of this.
CGI.pm
#!/usr/bin/perl
use CGI;

my $q = CGI->new;

print $q->header(‘text/plain’);
print “Hello World”;
Works under...
          CGI
        FastCGI
       mod_perl
HTTP::Server::Simple::CGI
CGI.pm

mod_perl    CGI     fastcgi



Apache       IIS    lighttpd
CGI.pm?
CGI.pm?
  meh
Frameworks
to the rescue!
Catalyst Maypole Mason Mojo Sledge Spoon
 PageKit AxKit Egg Gantry Continuity Solstice
 Mojolicious Tripletail Konstrukt Reaction Jifty
  Cyclone3 WebGUI OpenInteract Squatting
 Dancer CGI::Application Nanoa Ark Angelos
        Noe Schenker Tatsumaki Amon
Apache2::WebApp Web::Simple Apache2::REST
          SweetPea Hydrant Titanium
Let’s look how they
handled web servers.
CGI.pm

mod_perl    CGI     fastcgi



Apache       IIS    lighttpd
CGI::Application




Apache             IIS   lighttpd
CGI::Application




             CGI.pm




Apache             IIS   lighttpd
CGI::Application




             CGI.pm

 mod_perl          CGI   fastcgi



Apache             IIS   lighttpd
CGI::Application         Jifty




             CGI.pm

 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty         Catalyst




             CGI.pm

 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty               Catalyst




             CGI.pm                  Catalyst::Engine


 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty               Catalyst




             CGI.pm                  Catalyst::Engine


 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd          nginx
CGI::Application         Jifty               Catalyst




                            CGI.pm                  Catalyst::Engine


                mod_perl          CGI     fastcgi


HTTP::Server
  ::Simple     Apache             IIS      lighttpd          nginx
Mason          CGI::Application         Jifty               Catalyst




                            CGI.pm                  Catalyst::Engine


                mod_perl          CGI     fastcgi


HTTP::Server
  ::Simple     Apache             IIS      lighttpd          nginx
Mason           CGI::Application         Jifty               Catalyst




Mason::CGIHandler
                                 CGI.pm                  Catalyst::Engine


                     mod_perl          CGI     fastcgi


    HTTP::Server
      ::Simple      Apache             IIS      lighttpd          nginx
Gross.
CGI.pm
  Jifty, CGI::Application, Spoon


mod_perl centric
Mason, Sledge, PageKit, WebGUI


       Adapters
  Catalyst, Maypole, Squatting
That was 2008...
Gentleman thief &
            Double agent

Miyagawa
Acquired a great idea
 from Python/Ruby
WSGI (Python)
 Rack (Ruby)
WSGI (PEP-333)
WSGI Python Frameworks
 •   Django     •   mod_wsgi

 •   Bottle     •   Paste

 •   CherryPy   •   gunicorn

 •   Tornado    •   uWSGI

 •   Pylons     •   wsgiref

 •   Flask      •   Google AppEngine
Django              Bottle         Flask        Tornado


                                             WSGI middleware

                             WSGI


             wsgi handlers


Apache     lighttpd          nginx   mod_wsgi          GAE
Rack
Rack Ruby Frameworks
•   Rails     •   Unicorn

•   Merb      •   Thin

•   Sinatra   •   Mongrel

•   Camping   •   Rainbows!

•   Ramaze    •   Phusion Passenger

•   etc.      •   Heroku
Rails              Merb          Sinatra     Ramaze


                                         Rack middleware

                             Rack


             Rack handlers


Apache     lighttpd          Thin    Unicorn      Mongrel
Perl ?
PSGI     Perl ?
Perl Web Server Gateway Interface
Interface
Interface
Interface
PSGI != Plack
PSGI application
   code reference
   $app = sub {...};
# PSGI Hello World
my $app = sub {
   my $env = shift;
   return [
      200,
      [ ‘Content-Type’, ‘text/plain’ ],
      [ ‘Hello World’ ],
   ];
};
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

         CGI-like environment variables
          + psgi.input, psgi.errors etc.
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};


     HTTP status code (int.): 200, 404 etc.
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

        Array reference of header pairs:
        [ ‘Content-Type’, ‘text/html’, ... ]
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

  String, array reference of content chunks,
     Filehandle or IO::Handle-ish object
That’s it.
(There’s a callback based streaming interface as well)
# PSGI
my $app = sub {
   my $env = shift;
   return [
      200,
      [ ‘Content-Type’, ‘text/plain’ ],
      [ ‘Hello World’ ],
   ];
};
Now you’ve got
a PSGI compatible
   application.
Mason            CGI::App           Jifty               Catalyst




Mason::CGIHandler
                               CGI.pm               Catalyst::Engine


                    mod_perl    CGI       fastcgi


    HTTP::Server
      ::Simple      Apache       IIS       lighttpd          nginx
Catalyst            CGI::App              Jifty         Mason 2


                                                    Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI      mod_psgi   Perlbal
Catalyst            CGI::App              Jifty         Mason 2


                                                    Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI      mod_psgi   Perlbal


                     other PSGI Webservers
Web Servers
Plack::Handler
Connects PSGI compatible apps
      to Web servers...
FCGI
Plack::Handler::FCGI
Apache
Plack::Handler::Apache1
Plack::Handler::Apache2
Starman
UNIX Preforking HTTP servers (like Unicorn.rb)
  HTTP/1.1 chunk + keep-alives / Very Fast
HTTP::Server::Simple::PSGI
 Zero-deps other than HTTP::Server::Simple
    Best for embedding PSGI applications
Twiggy
    Non-blocking web server (like Thin.rb)
       based on AnyEvent framework




                Starlet
        Simpler UNIX HTTP/1.0 Server
Best used with Server::Starter and nginx/lighttpd
Perlbal plugin
http://github.com/miyagawa/Perlbal-Plugin-PSGI
nginx embedded perl
 http://github.com/yappo/nginx-psgi-patchs
mod_psgi
http://github.com/spiritloose/mod_psgi
                Apache2
Corona                             uWSGI
Coroutine for each connection      http://projects.unbit.it/uwsgi/
     based on Coro.pm


     Feersum                              evpsgi
http://github.com/stash/Feersum http://github.com/sekimura/evpsgi


                        Gepok
                 http://metacpan/module/Gepok
                  Pure Perl standalone HTTPS
                     First released July 2011
Frameworks                 Apps            Your own code


                                           Plack::Middleware

                               PSGI


   Plack::Handler::* (CGI, FCGI, Apache)
Frameworks                  Apps                     Your own code


                                                 Plack::Middleware

                                PSGI


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI   mod_psgi       Perlbal


Starman      Twiggy        uWSGI            Corona         etc, etc
25+ Plack::Handlers
Adoption?
Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI   mod_psgi     Perlbal


Starman      Twiggy        uWSGI            Corona          etc
?
                                                 Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI   mod_psgi     Perlbal


Starman      Twiggy        uWSGI            Corona          etc
Catalyst Maypole Mason Mojo Sledge Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI
  OpenInteract Squatting Dancer CGI::Application
 Nanoa Ark Angelos Noe Schenker Tatsumaki Amon
   Apache2::WebApp Web::Simple Apache2::REST
             SweetPea Hydrant Titanium
Catalyst Maypole Mason Mojo Sledge Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI
  OpenInteract Squatting Dancer CGI::Application
 Nanoa Ark Angelos Noe Schenker Tatsumaki Amon
   Apache2::WebApp Web::Simple Apache2::REST
             SweetPea Hydrant Titanium
PSGI Perl Frameworks
•   Amon               •   Hydrant       •   Schenker

•   Angelos            •   Jifty         •   Sledge

•   Ark                •   Mason         •   Squatting

•   Catalyst           •   Maypole       •   Tatsumaki

•   CGI::Application   •   Mojo          •   Titanium

•   Continuity         •   Mojolicious   •   Web::Simple

•   Dancer             •   Noe
Applications
        Movable Type 6
           WebGUI 8
                RT4
   ACT (conference toolkit)
Bricolage (if someone gets time)
Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI   mod_psgi     Perlbal


Starman      Twiggy        uWSGI            Corona   evpsgi
Catalyst            CGI::App               Jifty        Tatsumaki

   Dancer            Mojoliscious            MT6           Mason 2

 Web::Simple          WebGui 8               Mojo            etc...

                                                     Plack::Middleware

                  PSGI Compatible App


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI       mod_psgi     Perlbal


Starman      Twiggy        uWSGI            Corona       evpsgi
PSGI from a framework
use Dancer;

get ‘/’ => sub {
   “Hello World”;
};

dance;
use Mojolicious::Lite;

get ‘/:name’ => sub {
   my $self = shift;
   $self->render_text(‘Hello!’);
};

app->start;
use My::Jifty::App;

my $app = My::Jifty::App->psgi_app;
use Web::Simple ‘MyApp’;

package MyApp;

dispatch {
  sub(GET) {
    [ 200, [...], [ ‘Hello’ ] ];
  }
};

my $app = MyApp->as_psgi;
use My::Catalyst::App;

My::Catalyst::App->setup_engine(‘PSGI’);

my $app = sub {

  My::Catalyst::App->run(@_)

  };
catalyst.pl My::Catalyst::App
Plack
“PSGI implementation & toolkit”
Plack toolkit
Plack toolkit
Plack::Handlers   Connect PSGI apps and Web Servers
Plack toolkit
Plack::Handlers   Connect PSGI apps and Web Servers

   plackup        Command line launcher
Plack toolkit
Plack::Handlers   Connect PSGI apps and Web Servers

   plackup        Command line launcher

Plack::Loader     (auto)load Plack Servers
Plack toolkit
 Plack::Handlers    Connect PSGI apps and Web Servers

    plackup         Command line launcher

  Plack::Loader     (auto)load Plack Servers

Plack::Middleware   Easy-to-use PSGI Middleware
Plack toolkit
 Plack::Handlers    Connect PSGI apps and Web Servers

     plackup        Command line launcher

  Plack::Loader     (auto)load Plack Servers

Plack::Middleware   Easy-to-use PSGI Middleware

  Plack::Builder    OO & DSL to enable Middleware
Plack toolkit
 Plack::Handlers    Connect PSGI apps and Web Servers

     plackup        Command line launcher

  Plack::Loader     (auto)load Plack Servers

Plack::Middleware   Easy-to-use PSGI Middleware

  Plack::Builder    OO & DSL to enable Middleware

   Plack::Apps      Apps
Plack toolkit
 Plack::Handlers    Connect PSGI apps and Web Servers

     plackup        Command line launcher

  Plack::Loader     (auto)load Plack Servers

Plack::Middleware   Easy-to-use PSGI Middleware

  Plack::Builder    OO & DSL to enable Middleware

   Plack::Apps      Apps

   Plack::Test      Testing
plackup
Runs PSGI app instantly from CLI
      (inspired by rackup)
> plackup app.psgi
> plackup app.psgi
HTTP::Server::PSGI: Accepting
connections at http://0:5000/
HTTP::Server::PSGI
  Reference PSGI web server
       bundled in Plack

 Standalone, single-process HTTP server
    great for development and testing
Plack::Middleware
  (160+ modules - July 2011)
Middleware
        Debug, Session, Logger, Static, Lint,
AccessLog, ErrorDocument, StackTrace, Auth::Basic,
 Auth::Digest, ReverseProxy, Refresh, Auth::OAuth,
                    Throttle....
Chunked Class::Refresh Compile Conditional ConditionalGET
ConsoleLogger ContentLength ContentMD5 CrossOrigin
CSRFBlock Dancer::Debug DBIC::QueryLog Debug
Debug::CatalystPluginCache Debug::DBIC::QueryLog
Debug::DBIProfile Debug::Profiler::NYTProf Debug::W3CValidate
Deflater DoCoMoGUID Doorman ErrorDocument ESI ETag
Expires File::Sass Firebug::Lite FirePHP ForceEnv Head Header
HTMLify HTMLMinify HTTPExceptions IEnosniff IIS6ScriptNameFix
Image::Scale Inline InteractiveDebugger IPAddressFilter iPhone
JavaScript::Ectype JSConcat JSONP LighttpdScriptNameFix Lint
Log::Contextual Log::Minimal Log4perl LogDispatch LogWarn
MethodOverride Mirror NeverExpire NoDeflate NoMultipleSlashes
NullLogger Options OptionsOK Precompressed ProxyMap
RearrangeHeaders Recursive RefererCheck Refresh REPL Reproxy
ReverseProxy Rewrite Runtime Scope::Container Scope::Session
ServerStatus::Lite Session Session::SerializedCookie SetAccept
SimpleContentFilter SimpleLogger SizeLimit SocketIO SSI
StackTrace Static Static::Minifier StaticShared Status
Test::StashWarnings Throttle TMT UseChromeFrame Watermark
Plack Middleware
 Wraps a PSGI application
to add pre/post processing
Logging
Logging
Status code redirect
Logging
Status code redirect
Error Handler
Logging
Status code redirect
Error Handler
Cache Middleware
Logging
Status code redirect
Error Handler
Cache Middleware
Session Middleware
Logging
Status code redirect
Error Handler
Cache Middleware
Session Middleware
Routes Middleware
Logging
Status code redirect
Error Handler
Cache Middleware
Session Middleware
Routes Middleware
Your App
Plack::Middleware::A

      Plack::Middleware::B
                        PSGI Compatible App
Plack::Middleware::A

      Plack::Middleware::B
                        PSGI Compatible App




Request in
Plack::Middleware::A

      Plack::Middleware::B
                        PSGI Compatible App




Request in



        P::MW::A
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in



        P::MW::A


              P::MW::B
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in



        P::MW::A


              P::MW::B


                             PSGI App
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in



        P::MW::A


              P::MW::B                    P::MW::B


                             PSGI App
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in



        P::MW::A                               P::MW::A


              P::MW::B                    P::MW::B


                             PSGI App
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in                                           Response out



        P::MW::A                               P::MW::A


              P::MW::B                    P::MW::B


                             PSGI App
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in               e.g. Redirect               Response out



        P::MW::A                               P::MW::A


              P::MW::B                    P::MW::B


                             PSGI App
Plack::Middleware::A

      Plack::Middleware::B
                         PSGI Compatible App




Request in               e.g. Redirect                Response out



        P::MW::A                                P::MW::A
                             e.g. Static


              P::MW::B                     P::MW::B


                             PSGI App
Enabling
Plack::Middleware
  reusable and extensible
  Middleware framework
 Plack::Builder DSL in .psgi
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”;
   enable “B”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”;
   enable “B”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”;
   enable “B”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”;
   enable “B”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”; # Plack::Middleware::A
   enable “B”; # Order matters
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “A”;
   enable “B”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “Static”, root => “/htdocs”,
    path => qr!^/static/!;
   enable “Deflater”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “Static”, root => “/htdocs”,
    path => qr!^/static/!;
   enable “Deflater”;
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “Static”, root => “/htdocs”,
    path => qr!^/static/!;
   enable “Deflater”; # gzip/deflate
   $app;
}
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

return builder {
   enable “Static”, root => “/htdocs”,
    path => qr!^/static/!;
   enable “Deflater”;
   $app;
}
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in



             Static
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                        Response out
                        =~ ^/static

             Static
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                        Response out
                          =~ ^/static

             Static


                      -
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                        Response out
                          =~ ^/static

             Static


                      -


                              PSGI App
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                            Response out
                          =~ ^/static

             Static


                      -                   Deflate compresses


                              PSGI App
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                               Response out
                          =~ ^/static

             Static                                  -


                      -                   Deflate compresses


                              PSGI App
Plack::Middleware::Static

    Plack::Middleware::Deflate
                            PSGI Compatible App




Request in                                               Response out
                          =~ ^/static

             Static                                  -


                      -                   Deflate compresses


                              PSGI App
plackup compatible
plackup -e ‘enable “Foo”;’ app.psgi
Middleware
Write once, run in every framework
A few demos..
Assume...
use Plack::Builder;

my $body = ‘<html><body>Hello World</body></html>’;

my $app = sub {
  my $self = shift;

     return [200, ['Content-Type' => 'text/html'], [ $body ]];
};
Assume...
use Plack::Builder;

my $body = ‘<html><body>Hello World</body></html>’;

my $app = sub {
  my $self = shift;

     return [200, ['Content-Type' => 'text/html'], [ $body ]];
};
Assume...
use Plack::Builder;

my $body = ‘<html><body>Hello World</body></html>’;

my $app = sub {
  my $self = shift;

     return [200, ['Content-Type' => 'text/html'], [ $body ]];
};
Debugger
return builder {
   # Precious debug info. Right on your page!
   enable 'Debug';

    $app;
}
InteractiveDebugger
my $app = sub {
  my $foo = 'bar';
  die "oops" if $foo eq 'bar';

     [200, ['Content-Type' => 'text/html'], [ $body ]];
};

return builder {
   # Enable Interactive debugging
   enable "InteractiveDebugger";

     $app;
}
my $app = sub {
  my $foo = 'bar';
  die "oops" if $foo eq 'bar';

     [200, ['Content-Type' => 'text/html'], [ $body ]];
};

return builder {
   # Enable Interactive debugging
   enable "InteractiveDebugger";

     $app;
}
my $app = sub {
  my $foo = 'bar';
  die "oops" if $foo eq 'bar';

     [200, ['Content-Type' => 'text/html'], [ $body ]];
};

return builder {
   # Enable Interactive debugging
   enable "InteractiveDebugger";

     $app;
}
NYTProf - profiler
First rule of Program
    Optimisation
Don’t do it!
Second rule of Program
      Optimisation
   (for experts only)
Don’t do it -
   yet!
return builder {
   enable 'Debug', panels => [ [ 'Profiler::NYTProf' ] ];
   $app;
};
ServerStatus::Lite
use Plack::Builder;

return builder {
   enable "ServerStatus::Lite",
     path => '/server-status',
     allow => [ '127.0.0.1'],
     scoreboard => '/tmp/score';
   $app;
}
SizeLimit
use Plack::Builder;

return builder {
   enable "SizeLimit",
     max_unshared_size_in_kb => 3000,
     check_every_n_requests => 5;
   $app;
}
Plack::App::*
ready-to-use applications
Apache::ActionWrapper CGIBin Cascade
CocProxy DAV Directory Directory::Xslate
FCGIDispatcher File ImageMagick JSP PSGIBin
Path::Router Proxy
Proxy::Backend::AnyEvent::HTTP
Proxy::Backend::LWP Proxy::Selective Proxy::Test
URLMap WrapApacheReq
WrapApacheReq::FakeRequest WrapCGI
Plack::App::CGIBin
mount /cgi-bin as PSGI applications
CGI::PSGI
Easy migration from CGI.pm
Plack::App::Directory
   Static content file server
Plack::App::Proxy
    (non-blocking) proxy server
Can be used as reverse proxy as well
Plack::App::JSP
Runs JavaScript PSGI apps :)
# app.psgi - Javascript!
Plack::App::JSP->new( js => q{
  function respond(body) {
    return [ 200, [ 'Content-type', 'text/html' ], [ body ] ]
  }

   respond("Five factorial is " +
      (function(x) {
        if ( x<2 ) return x;
        return x * arguments.callee(x - 1);
      })(5)
   );
});
# app.psgi - Javascript!
Plack::App::JSP->new( js => q{
  function respond(body) {
    return [ 200, [ 'Content-type', 'text/html' ], [ body ] ]
  }

   respond("Five factorial is " +
      (function(x) {
        if ( x<2 ) return x;
        return x * arguments.callee(x - 1);
      })(5)
   );
});
Plack::App::URLMap
    Multiplex multiple apps
 Integrated with Builder DSL
use CatApp;
use CGIApp;

my $c1 = sub { CatApp->run };
my $c2 = sub { CGIApp->run_psgi };

use Plack::Builder;

return builder {
  mount “/cat” => $c1;
  mount “/cgi-app” => builder {
    enable “StackTrace”;
    $c2;
  };
}
use CatApp;
use CGIApp;

my $c1 = sub { CatApp->run };
my $c2 = sub { CGIApp->run_psgi };

use Plack::Builder;

return builder {
  mount “/cat” => $c1;
  mount “/cgi-app” => builder {
    enable “StackTrace”;
    $c2;
  };
}
use CatApp;
use CGIApp;

my $c1 = sub { CatApp->run };
my $c2 = sub { CGIApp->run_psgi };

use Plack::Builder;

return builder {
  mount “/cat” => $c1;
  mount “/cgi-app” => builder {
    enable “StackTrace”;
    $c2;
  };
}
Some more demos...
Basic website
TemplateToolkit +
     Static
my $root = '/path/to/html_doc_root';

my $app = Plack::Middleware::TemplateToolkit->new(
   INCLUDE_PATH => root,
)->to_app;

return builder {

    enable 'Static',
      path =>
         qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$},
      root => $root;

    $app;
}
my $root = '/path/to/html_doc_root';

my $app = Plack::Middleware::TemplateToolkit->new(
   INCLUDE_PATH => root,
)->to_app;

return builder {

    enable 'Static',
      path =>
         qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$},
      root => $root;

    $app;
}
my $root = '/path/to/html_doc_root';

my $app = Plack::Middleware::TemplateToolkit->new(
   INCLUDE_PATH => root,
)->to_app;

return builder {

    enable 'Static',
      path =>
         qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$},
      root => $root;

    $app;
}
my $root = '/path/to/html_doc_root';

my $app = Plack::Middleware::TemplateToolkit->new(
   INCLUDE_PATH => root,
)->to_app;

return builder {

    enable 'Static',
      path =>
         qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$},
      root => $root;

    $app;
}
my $root = '/path/to/html_doc_root';

my $app = Plack::Middleware::TemplateToolkit->new(
   INCLUDE_PATH => root,
)->to_app;

return builder {

    enable 'Static',
      path =>
         qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$},
      root => $root;

    $app;
}
Creating utilities
Caching Proxy
Website
Website




Developing code
Website




Developing code
Slow website
    Website




Developing code
Slow website




Developing code
Slow website




 Caching Proxy




Developing code
use Plack::Middleware::Cache;
use Plack::App::Proxy;

my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

return builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache';
   $app;
};
use Plack::Middleware::Cache;
use Plack::App::Proxy;

my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

return builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache';
   $app;
};
use Plack::Middleware::Cache;
use Plack::App::Proxy;

my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

return builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache';
   $app;
};
use LWP::Simple;

my $content = get(‘http://localhost:5000/’);
Caching Proxy +
 Domain hijack
use LWP::Simple;

my $content = get(‘http://localhost:5000/’);
use LWP::Simple;

my $content = get(‘http://london.pm.org/’);
my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

return builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache2';
   $app;
};
my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

return builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache2';
   $app;
};
my $app
  = Plack::App::Proxy->new(
     remote => "http://london.pm.org/" )->to_app;

$app = builder {
   enable "Cache",
     match_url => '^/.*',        # everything
     cache_dir => '/tmp/plack-cache2';
   $app;
};
# Hijack Any LWP::Useragent requests
LWP::Protocol::PSGI->register($app);

use LWP::Simple;

my $content = get("http://london.pm.org/");

say 'o/' if $content =~ /London Perl Mongers/;
# Hijack Any LWP::Useragent requests
LWP::Protocol::PSGI->register($app);

use LWP::Simple;

my $content = get("http://london.pm.org/");

say 'o/' if $content =~ /London Perl Mongers/;
# Hijack Any LWP::Useragent requests
LWP::Protocol::PSGI->register($app);

use LWP::Simple;

my $content = get("http://london.pm.org/");

say 'o/' if $content =~ /London Perl Mongers/;
# Hijack Any LWP::Useragent requests
LWP::Protocol::PSGI->register($app);

use LWP::Simple;

my $content = get("http://london.pm.org/");

say 'o/' if $content =~ /London Perl Mongers/;
Plack::Test
Unified interface to write TAP tests
 with Mock HTTP and Live HTTP
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi
    app => $app,
    client => sub {
           my $callback = shift;
           my $req = GET “http://localhost/foo”;
            my $res = $callback->($req);
            ok $res->[0] == ‘200’, ‘Success’;
    };
Test::WWW::Mechanize::PSGI
use Test::WWW::Mechanize::PSGI;
 
my $mech =
    Test::WWW::Mechanize::PSGI->new(
     app => $app,
    );

$mech->get_ok('/');
use Test::WWW::Mechanize::PSGI;
 
my $mech =
    Test::WWW::Mechanize::PSGI->new(
     app => $app,
    );

$mech->get_ok('/');
Testing your full configuration!
Network setup tip
Use a reverse proxy
Use a reverse proxy
• Sits in front of servers, not clients - “reverse”
Use a reverse proxy
• Sits in front of servers, not clients - “reverse”
• Makes servers more efficient
Use a reverse proxy
• Sits in front of servers, not clients - “reverse”
• Makes servers more efficient
• Add HTTPS easily
Use a reverse proxy
• Sits in front of servers, not clients - “reverse”
• Makes servers more efficient
• Add HTTPS easily
• Makes scaling easier
Internet / Users




Webserver App
Internet / Users




Webserver App
Internet / Users




Webserver App
Internet / Users




Webserver App
Internet / Users

 Reverse Proxy
 NGINX   Perlbal   Pound




Webserver App
Internet / Users

 Reverse Proxy
 NGINX   Perlbal   Pound




Webserver App
Internet / Users

 Reverse Proxy
 NGINX   Perlbal   Pound




Webserver App
Internet / Users

 Reverse Proxy
 NGINX   Perlbal   Pound




Webserver App
Internet / Users

 Reverse Proxy
 NGINX   Perlbal   Pound




Webserver App
Reverse Proxy
NGINX    Perlbal   Pound




        Server
Reverse Proxy
  NGINX    Perlbal      Pound




Server 1             Server 2
Reverse Proxy
     NGINX     Perlbal   Pound




Server 1                  Server 3

             Server 2
Reverse Proxy
     NGINX     Perlbal   Pound




Server 1                  Server 3

             Server 2
Plack::Middleware::ReverseProxy

          Updates
 $env->{REMOTE_ADDRESS}
Why use Plack?
Why use Plack?
‣ Flexibility
‣ Middleware
‣ Apps
‣ Development
‣ Testing
‣ Deployment
Flexibility

    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI   mod_psgi   Perlbal


Starman      Twiggy        uWSGI            Corona    etc
Flexibility
• Easy to change webserver (25+!)
        Plack::Handler::* (CGI, FCGI, Apache)


    Apache       lighttpd       HTTP::Server::PSGI   mod_psgi   Perlbal


    Starman      Twiggy        uWSGI            Corona    etc
Flexibility
• Easy to change webserver (25+!)
        Plack::Handler::* (CGI, FCGI, Apache)


    Apache       lighttpd       HTTP::Server::PSGI   mod_psgi   Perlbal


    Starman      Twiggy        uWSGI            Corona    etc




• Starman seems to be used most
Middleware
Middleware


• Easy to reuse with any PSGI app
Middleware


• Easy to reuse with any PSGI app
• Many tools to make your life easy
Middleware


• Easy to reuse with any PSGI app
• Many tools to make your life easy
• 160+ on CPAN now
App
App


• URLMapping / Routing
App


• URLMapping / Routing
• Static files
App


• URLMapping / Routing
• Static files
• Proxying
Development
Development

• plackup
Development

• plackup
• Restarter (monitor changes on disk)
Development

• plackup
• Restarter (monitor changes on disk)
• HTTP::Server::PSGI
Development

• plackup
• Restarter (monitor changes on disk)
• HTTP::Server::PSGI
• Debugging middleware
Development

• plackup
• Restarter (monitor changes on disk)
• HTTP::Server::PSGI
• Debugging middleware
• Profiler
Testing
Testing


• Testing your full configuration
Testing


• Testing your full configuration
• Test::WWW::Mechanize::PSGI
Testing


• Testing your full configuration
• Test::WWW::Mechanize::PSGI
• Plack::Test
Deployment
Deployment


• No separate configuration files
Deployment


• No separate configuration files
• Easy to choose/change webserver
Deployment


• No separate configuration files
• Easy to choose/change webserver
• DotCloud etc - cloud deployment
Summary
Summary
✦ PSGI is an interface, Plack is the code.
Summary
✦ PSGI is an interface, Plack is the code.
✦ Many fast PSGI servers.
Summary
✦ PSGI is an interface, Plack is the code.
✦ Many fast PSGI servers.
✦ Adapters and tools for frameworks and
  webservers.
Summary
✦ PSGI is an interface, Plack is the code.
✦ Many fast PSGI servers.
✦ Adapters and tools for frameworks and
  webservers.
✦ An amazing amount of middleware
Summary
✦ PSGI is an interface, Plack is the code.
✦ Many fast PSGI servers.
✦ Adapters and tools for frameworks and
  webservers.
✦ An amazing amount of middleware
✦ Used in many production systems
Use Plack
Thank you!
Slides: http://slideshare.net/ranguard

        http://plackperl.org/

      irc://irc.perl.org/#plack

More Related Content

What's hot

Simple callcenter platform with PHP
Simple callcenter platform with PHPSimple callcenter platform with PHP
Simple callcenter platform with PHPMorten Amundsen
 
Accelerate Quality with Postman - Basics
Accelerate Quality with Postman - BasicsAccelerate Quality with Postman - Basics
Accelerate Quality with Postman - BasicsKnoldus Inc.
 
Android Zararlı Yazılım Analizi
Android Zararlı Yazılım AnaliziAndroid Zararlı Yazılım Analizi
Android Zararlı Yazılım AnaliziBGA Cyber Security
 
Making a Headless Android Device
Making a Headless Android DeviceMaking a Headless Android Device
Making a Headless Android DevicePatricia Aas
 
2021.laravelconf.tw.slides1
2021.laravelconf.tw.slides12021.laravelconf.tw.slides1
2021.laravelconf.tw.slides1LiviaLiaoFontech
 
Histograms at scale - Monitorama 2019
Histograms at scale - Monitorama 2019Histograms at scale - Monitorama 2019
Histograms at scale - Monitorama 2019Evan Chan
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to AnsibleKnoldus Inc.
 
ARI and AGI, a powerful combination
ARI and AGI, a powerful combinationARI and AGI, a powerful combination
ARI and AGI, a powerful combinationJöran Vinzens
 
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-V
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-VRISC-V on Edge: Porting EVE and Alpine Linux to RISC-V
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-VScyllaDB
 
Network Scanning Phases and Supporting Tools
Network Scanning Phases and Supporting ToolsNetwork Scanning Phases and Supporting Tools
Network Scanning Phases and Supporting ToolsJoseph Bugeja
 
5 p9 pnor and open bmc overview - final
5 p9 pnor and open bmc overview - final5 p9 pnor and open bmc overview - final
5 p9 pnor and open bmc overview - finalYutaka Kawai
 
The Integration of Laravel with Swoole
The Integration of Laravel with SwooleThe Integration of Laravel with Swoole
The Integration of Laravel with SwooleAlbert Chen
 
Suricata ile siber tehdit avcılığı
Suricata ile siber tehdit avcılığıSuricata ile siber tehdit avcılığı
Suricata ile siber tehdit avcılığıKurtuluş Karasu
 
Module 19 (evading ids, firewalls and honeypots)
Module 19 (evading ids, firewalls and honeypots)Module 19 (evading ids, firewalls and honeypots)
Module 19 (evading ids, firewalls and honeypots)Wail Hassan
 
Pet Pen Testing Tools: Zenmap & Nmap
Pet Pen Testing Tools: Zenmap & NmapPet Pen Testing Tools: Zenmap & Nmap
Pet Pen Testing Tools: Zenmap & NmapMatt Vieyra
 

What's hot (20)

Simple callcenter platform with PHP
Simple callcenter platform with PHPSimple callcenter platform with PHP
Simple callcenter platform with PHP
 
Accelerate Quality with Postman - Basics
Accelerate Quality with Postman - BasicsAccelerate Quality with Postman - Basics
Accelerate Quality with Postman - Basics
 
Android Zararlı Yazılım Analizi
Android Zararlı Yazılım AnaliziAndroid Zararlı Yazılım Analizi
Android Zararlı Yazılım Analizi
 
Making a Headless Android Device
Making a Headless Android DeviceMaking a Headless Android Device
Making a Headless Android Device
 
2021.laravelconf.tw.slides1
2021.laravelconf.tw.slides12021.laravelconf.tw.slides1
2021.laravelconf.tw.slides1
 
Nmap
NmapNmap
Nmap
 
Histograms at scale - Monitorama 2019
Histograms at scale - Monitorama 2019Histograms at scale - Monitorama 2019
Histograms at scale - Monitorama 2019
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
 
ARI and AGI, a powerful combination
ARI and AGI, a powerful combinationARI and AGI, a powerful combination
ARI and AGI, a powerful combination
 
Recon for Bug Bounty by Agnibha Dutta.pdf
Recon for Bug Bounty by Agnibha  Dutta.pdfRecon for Bug Bounty by Agnibha  Dutta.pdf
Recon for Bug Bounty by Agnibha Dutta.pdf
 
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-V
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-VRISC-V on Edge: Porting EVE and Alpine Linux to RISC-V
RISC-V on Edge: Porting EVE and Alpine Linux to RISC-V
 
Network Scanning Phases and Supporting Tools
Network Scanning Phases and Supporting ToolsNetwork Scanning Phases and Supporting Tools
Network Scanning Phases and Supporting Tools
 
5 p9 pnor and open bmc overview - final
5 p9 pnor and open bmc overview - final5 p9 pnor and open bmc overview - final
5 p9 pnor and open bmc overview - final
 
Bug bounty recon.pdf
Bug bounty recon.pdfBug bounty recon.pdf
Bug bounty recon.pdf
 
The Integration of Laravel with Swoole
The Integration of Laravel with SwooleThe Integration of Laravel with Swoole
The Integration of Laravel with Swoole
 
Suricata ile siber tehdit avcılığı
Suricata ile siber tehdit avcılığıSuricata ile siber tehdit avcılığı
Suricata ile siber tehdit avcılığı
 
Wireshark
WiresharkWireshark
Wireshark
 
Using Logstash, elasticsearch & kibana
Using Logstash, elasticsearch & kibanaUsing Logstash, elasticsearch & kibana
Using Logstash, elasticsearch & kibana
 
Module 19 (evading ids, firewalls and honeypots)
Module 19 (evading ids, firewalls and honeypots)Module 19 (evading ids, firewalls and honeypots)
Module 19 (evading ids, firewalls and honeypots)
 
Pet Pen Testing Tools: Zenmap & Nmap
Pet Pen Testing Tools: Zenmap & NmapPet Pen Testing Tools: Zenmap & Nmap
Pet Pen Testing Tools: Zenmap & Nmap
 

Viewers also liked

Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 
Modern Core Perl
Modern Core PerlModern Core Perl
Modern Core PerlDave Cross
 
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First EditionPerl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First Editiontutorialsruby
 
Your first website in under a minute with Dancer
Your first website in under a minute with DancerYour first website in under a minute with Dancer
Your first website in under a minute with DancerxSawyer
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of ThingsDave Cross
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Tatsuhiko Miyagawa
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in PerlNaveen Gupta
 
Mojolicious. The web in a box!
Mojolicious. The web in a box!Mojolicious. The web in a box!
Mojolicious. The web in a box!Anatoly Sharifulin
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Masahiro Nagano
 
Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Arpad Szasz
 
Iglesia asamblea de dios
Iglesia asamblea de diosIglesia asamblea de dios
Iglesia asamblea de diosLucasLagos
 
Discover JustFab success story with Lengow
Discover JustFab success story with LengowDiscover JustFab success story with Lengow
Discover JustFab success story with LengowLengow
 
Presentacion Reunion 24 01 09
Presentacion Reunion 24 01 09Presentacion Reunion 24 01 09
Presentacion Reunion 24 01 09pedro_i
 
Pie diabetico..
Pie diabetico..Pie diabetico..
Pie diabetico..alromaes
 
Ppt 10 july 2007 2032
Ppt 10 july 2007 2032Ppt 10 july 2007 2032
Ppt 10 july 2007 2032Miguel Mares
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 

Viewers also liked (20)

Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 
Modern Core Perl
Modern Core PerlModern Core Perl
Modern Core Perl
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TWPSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
 
Dancer's Ecosystem
Dancer's EcosystemDancer's Ecosystem
Dancer's Ecosystem
 
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First EditionPerl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
 
Your first website in under a minute with Dancer
Your first website in under a minute with DancerYour first website in under a minute with Dancer
Your first website in under a minute with Dancer
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of Things
 
Plack at OSCON 2010
Plack at OSCON 2010Plack at OSCON 2010
Plack at OSCON 2010
 
Message passing
Message passingMessage passing
Message passing
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in Perl
 
Mojolicious. The web in a box!
Mojolicious. The web in a box!Mojolicious. The web in a box!
Mojolicious. The web in a box!
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
 
Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013
 
Iglesia asamblea de dios
Iglesia asamblea de diosIglesia asamblea de dios
Iglesia asamblea de dios
 
Discover JustFab success story with Lengow
Discover JustFab success story with LengowDiscover JustFab success story with Lengow
Discover JustFab success story with Lengow
 
Presentacion Reunion 24 01 09
Presentacion Reunion 24 01 09Presentacion Reunion 24 01 09
Presentacion Reunion 24 01 09
 
Pie diabetico..
Pie diabetico..Pie diabetico..
Pie diabetico..
 
Ppt 10 july 2007 2032
Ppt 10 july 2007 2032Ppt 10 july 2007 2032
Ppt 10 july 2007 2032
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 

Similar to Plack basics for Perl websites - YAPC::EU 2011

Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversTatsuhiko Miyagawa
 
Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Yuji Takayama
 
Apache2 BootCamp : Serving Dynamic Content with CGI
Apache2 BootCamp : Serving Dynamic Content with CGIApache2 BootCamp : Serving Dynamic Content with CGI
Apache2 BootCamp : Serving Dynamic Content with CGIWildan Maulana
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmsom_nangia
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmwilburlo
 
Developing Brilliant and Powerful APIs in Ruby & Python
Developing Brilliant and Powerful APIs in Ruby & PythonDeveloping Brilliant and Powerful APIs in Ruby & Python
Developing Brilliant and Powerful APIs in Ruby & PythonSmartBear
 
Developing Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScriptDeveloping Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScriptnohuhu
 
Building dynamic websites with Mod perl and apache
Building dynamic websites with Mod perl and apacheBuilding dynamic websites with Mod perl and apache
Building dynamic websites with Mod perl and apacheKamal Nayan
 
Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Andrea Scuderi
 
Mastering Microservices with Kong (DevoxxUK 2019)
Mastering Microservices with Kong (DevoxxUK 2019)Mastering Microservices with Kong (DevoxxUK 2019)
Mastering Microservices with Kong (DevoxxUK 2019)Maarten Mulders
 
Beware the potholes
Beware the potholesBeware the potholes
Beware the potholesYan Cui
 
Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014 Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014 OSSCube
 
Docs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlDocs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlAkramWaseem
 
State of Developer Tools (WDS09)
State of Developer Tools (WDS09)State of Developer Tools (WDS09)
State of Developer Tools (WDS09)bgalbs
 
Kubernetes API code-base tour
Kubernetes API code-base tourKubernetes API code-base tour
Kubernetes API code-base tourStefan Schimanski
 

Similar to Plack basics for Perl websites - YAPC::EU 2011 (20)

Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012
 
Apache2 BootCamp : Serving Dynamic Content with CGI
Apache2 BootCamp : Serving Dynamic Content with CGIApache2 BootCamp : Serving Dynamic Content with CGI
Apache2 BootCamp : Serving Dynamic Content with CGI
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Crafting APIs
Crafting APIsCrafting APIs
Crafting APIs
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Developing Brilliant and Powerful APIs in Ruby & Python
Developing Brilliant and Powerful APIs in Ruby & PythonDeveloping Brilliant and Powerful APIs in Ruby & Python
Developing Brilliant and Powerful APIs in Ruby & Python
 
Developing Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScriptDeveloping Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScript
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Building dynamic websites with Mod perl and apache
Building dynamic websites with Mod perl and apacheBuilding dynamic websites with Mod perl and apache
Building dynamic websites with Mod perl and apache
 
Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020Aws Lambda in Swift - NSLondon - 3rd December 2020
Aws Lambda in Swift - NSLondon - 3rd December 2020
 
Mastering Microservices with Kong (DevoxxUK 2019)
Mastering Microservices with Kong (DevoxxUK 2019)Mastering Microservices with Kong (DevoxxUK 2019)
Mastering Microservices with Kong (DevoxxUK 2019)
 
Beware the potholes
Beware the potholesBeware the potholes
Beware the potholes
 
Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014 Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014
 
Docs Python Org Howto Webservers Html
Docs Python Org Howto Webservers HtmlDocs Python Org Howto Webservers Html
Docs Python Org Howto Webservers Html
 
State of Developer Tools (WDS09)
State of Developer Tools (WDS09)State of Developer Tools (WDS09)
State of Developer Tools (WDS09)
 
Kubernetes API code-base tour
Kubernetes API code-base tourKubernetes API code-base tour
Kubernetes API code-base tour
 

More from leo lapworth

AWS CDK introduction
AWS CDK introductionAWS CDK introduction
AWS CDK introductionleo lapworth
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
Evolving Architecture - Further
Evolving Architecture - FurtherEvolving Architecture - Further
Evolving Architecture - Furtherleo lapworth
 
Evolving Archetecture
Evolving ArchetectureEvolving Archetecture
Evolving Archetectureleo lapworth
 

More from leo lapworth (6)

AWS CDK introduction
AWS CDK introductionAWS CDK introduction
AWS CDK introduction
 
Gitalist
GitalistGitalist
Gitalist
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Evolving Architecture - Further
Evolving Architecture - FurtherEvolving Architecture - Further
Evolving Architecture - Further
 
Evolving Archetecture
Evolving ArchetectureEvolving Archetecture
Evolving Archetecture
 

Recently uploaded

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 

Recently uploaded (20)

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 

Plack basics for Perl websites - YAPC::EU 2011

  • 1. Plack Basics Leo Lapworth @ YAPC::EU 2011 Much content from Tatsuhiko Miyagawa’s YAPC::NA 2010 talk
  • 3. What is Plack? “Superglue for Perl 5 Web Frameworks and Web Servers”
  • 4. How will that help me?
  • 5. How will that help me? ‣ Flexibility
  • 6. How will that help me? ‣ Flexibility ‣ Middleware (plugins)
  • 7. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps
  • 8. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps ‣ Development
  • 9. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps ‣ Development ‣ Testing
  • 10. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps ‣ Development ‣ Testing ‣ Deployment
  • 11. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps ‣ Development ‣ Testing ‣ Deployment ‣ World peace
  • 12. How will that help me? ‣ Flexibility ‣ Middleware (plugins) ‣ Apps ‣ Development ‣ Testing ‣ Deployment ‣ World peace
  • 15. #!/usr/bin/perl use strict; print “Content-Type: text/plainrnrn”; print “Hello World”;
  • 16. package HelloWorld; use strict; use Apache::RequestRec; use Apache::RequestIO; use Apache::Const -compile => qw(OK); sub handler { my $r = shift; $r->content_type(‘text/plain’); $r->print(“Hello World”); return Apache::Const::OK; } 1;
  • 17. use FCGI; my $req = FCGI::Request(); while ($req->Accept >= 0) { print “Content-Type: text/plainrnrn”; print “Hello World”; }
  • 18. package HelloWorld; use base qw(HTTP::Server::Simple::CGI); sub handle_request { my($self, $cgi) = @_; print “HTTP/1.0 200 OKrn”; print “Content-Type: text/plainrnrn”; print “Hello World”; } 1;
  • 20. Painful to support all of them 
  • 21. There was one common way to do all of this.
  • 23. #!/usr/bin/perl use CGI; my $q = CGI->new; print $q->header(‘text/plain’); print “Hello World”;
  • 24. Works under... CGI FastCGI mod_perl HTTP::Server::Simple::CGI
  • 25. CGI.pm mod_perl CGI fastcgi Apache IIS lighttpd
  • 29.
  • 30. Catalyst Maypole Mason Mojo Sledge Spoon PageKit AxKit Egg Gantry Continuity Solstice Mojolicious Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI OpenInteract Squatting Dancer CGI::Application Nanoa Ark Angelos Noe Schenker Tatsumaki Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  • 31. Let’s look how they handled web servers.
  • 32. CGI.pm mod_perl CGI fastcgi Apache IIS lighttpd
  • 33. CGI::Application Apache IIS lighttpd
  • 34. CGI::Application CGI.pm Apache IIS lighttpd
  • 35. CGI::Application CGI.pm mod_perl CGI fastcgi Apache IIS lighttpd
  • 36. CGI::Application Jifty CGI.pm mod_perl CGI fastcgi Apache IIS lighttpd
  • 37. CGI::Application Jifty Catalyst CGI.pm mod_perl CGI fastcgi Apache IIS lighttpd
  • 38. CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgi Apache IIS lighttpd
  • 39. CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgi Apache IIS lighttpd nginx
  • 40. CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
  • 41. Mason CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
  • 42. Mason CGI::Application Jifty Catalyst Mason::CGIHandler CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
  • 44. CGI.pm Jifty, CGI::Application, Spoon mod_perl centric Mason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
  • 46. Gentleman thief & Double agent Miyagawa
  • 47. Acquired a great idea from Python/Ruby
  • 50. WSGI Python Frameworks • Django • mod_wsgi • Bottle • Paste • CherryPy • gunicorn • Tornado • uWSGI • Pylons • wsgiref • Flask • Google AppEngine
  • 51. Django Bottle Flask Tornado WSGI middleware WSGI wsgi handlers Apache lighttpd nginx mod_wsgi GAE
  • 52. Rack
  • 53. Rack Ruby Frameworks • Rails • Unicorn • Merb • Thin • Sinatra • Mongrel • Camping • Rainbows! • Ramaze • Phusion Passenger • etc. • Heroku
  • 54. Rails Merb Sinatra Ramaze Rack middleware Rack Rack handlers Apache lighttpd Thin Unicorn Mongrel
  • 56. PSGI Perl ? Perl Web Server Gateway Interface
  • 60. PSGI application code reference $app = sub {...};
  • 61. # PSGI Hello World my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 62. my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; CGI-like environment variables + psgi.input, psgi.errors etc.
  • 63. my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; HTTP status code (int.): 200, 404 etc.
  • 64. my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; Array reference of header pairs: [ ‘Content-Type’, ‘text/html’, ... ]
  • 65. my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; String, array reference of content chunks, Filehandle or IO::Handle-ish object
  • 66. That’s it. (There’s a callback based streaming interface as well)
  • 67. # PSGI my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 68. Now you’ve got a PSGI compatible application.
  • 69. Mason CGI::App Jifty Catalyst Mason::CGIHandler CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
  • 70. Catalyst CGI::App Jifty Mason 2 Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
  • 71. Catalyst CGI::App Jifty Mason 2 Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal other PSGI Webservers
  • 73. Plack::Handler Connects PSGI compatible apps to Web servers...
  • 76. Starman UNIX Preforking HTTP servers (like Unicorn.rb) HTTP/1.1 chunk + keep-alives / Very Fast
  • 77. HTTP::Server::Simple::PSGI Zero-deps other than HTTP::Server::Simple Best for embedding PSGI applications
  • 78. Twiggy Non-blocking web server (like Thin.rb) based on AnyEvent framework Starlet Simpler UNIX HTTP/1.0 Server Best used with Server::Starter and nginx/lighttpd
  • 80. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
  • 82. Corona uWSGI Coroutine for each connection http://projects.unbit.it/uwsgi/ based on Coro.pm Feersum evpsgi http://github.com/stash/Feersum http://github.com/sekimura/evpsgi Gepok http://metacpan/module/Gepok Pure Perl standalone HTTPS First released July 2011
  • 83. Frameworks Apps Your own code Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache)
  • 84. Frameworks Apps Your own code Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc, etc
  • 87. Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc
  • 88. ? Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc
  • 89. Catalyst Maypole Mason Mojo Sledge Spoon PageKit AxKit Egg Gantry Continuity Solstice Mojolicious Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI OpenInteract Squatting Dancer CGI::Application Nanoa Ark Angelos Noe Schenker Tatsumaki Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  • 90. Catalyst Maypole Mason Mojo Sledge Spoon PageKit AxKit Egg Gantry Continuity Solstice Mojolicious Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI OpenInteract Squatting Dancer CGI::Application Nanoa Ark Angelos Noe Schenker Tatsumaki Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  • 91. PSGI Perl Frameworks • Amon • Hydrant • Schenker • Angelos • Jifty • Sledge • Ark • Mason • Squatting • Catalyst • Maypole • Tatsumaki • CGI::Application • Mojo • Titanium • Continuity • Mojolicious • Web::Simple • Dancer • Noe
  • 92. Applications Movable Type 6 WebGUI 8 RT4 ACT (conference toolkit) Bricolage (if someone gets time)
  • 93. Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona evpsgi
  • 94. Catalyst CGI::App Jifty Tatsumaki Dancer Mojoliscious MT6 Mason 2 Web::Simple WebGui 8 Mojo etc... Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona evpsgi
  • 95. PSGI from a framework
  • 96. use Dancer; get ‘/’ => sub { “Hello World”; }; dance;
  • 97. use Mojolicious::Lite; get ‘/:name’ => sub { my $self = shift; $self->render_text(‘Hello!’); }; app->start;
  • 98. use My::Jifty::App; my $app = My::Jifty::App->psgi_app;
  • 99. use Web::Simple ‘MyApp’; package MyApp; dispatch { sub(GET) { [ 200, [...], [ ‘Hello’ ] ]; } }; my $app = MyApp->as_psgi;
  • 101.
  • 102.
  • 103.
  • 107. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers
  • 108. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher
  • 109. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack Servers
  • 110. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack Servers Plack::Middleware Easy-to-use PSGI Middleware
  • 111. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack Servers Plack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware
  • 112. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack Servers Plack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware Plack::Apps Apps
  • 113. Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack Servers Plack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware Plack::Apps Apps Plack::Test Testing
  • 114. plackup Runs PSGI app instantly from CLI (inspired by rackup)
  • 116. > plackup app.psgi HTTP::Server::PSGI: Accepting connections at http://0:5000/
  • 117. HTTP::Server::PSGI Reference PSGI web server bundled in Plack Standalone, single-process HTTP server great for development and testing
  • 118. Plack::Middleware (160+ modules - July 2011)
  • 119. Middleware Debug, Session, Logger, Static, Lint, AccessLog, ErrorDocument, StackTrace, Auth::Basic, Auth::Digest, ReverseProxy, Refresh, Auth::OAuth, Throttle....
  • 120.
  • 121. Chunked Class::Refresh Compile Conditional ConditionalGET ConsoleLogger ContentLength ContentMD5 CrossOrigin CSRFBlock Dancer::Debug DBIC::QueryLog Debug Debug::CatalystPluginCache Debug::DBIC::QueryLog Debug::DBIProfile Debug::Profiler::NYTProf Debug::W3CValidate Deflater DoCoMoGUID Doorman ErrorDocument ESI ETag Expires File::Sass Firebug::Lite FirePHP ForceEnv Head Header HTMLify HTMLMinify HTTPExceptions IEnosniff IIS6ScriptNameFix Image::Scale Inline InteractiveDebugger IPAddressFilter iPhone JavaScript::Ectype JSConcat JSONP LighttpdScriptNameFix Lint Log::Contextual Log::Minimal Log4perl LogDispatch LogWarn MethodOverride Mirror NeverExpire NoDeflate NoMultipleSlashes NullLogger Options OptionsOK Precompressed ProxyMap RearrangeHeaders Recursive RefererCheck Refresh REPL Reproxy ReverseProxy Rewrite Runtime Scope::Container Scope::Session ServerStatus::Lite Session Session::SerializedCookie SetAccept SimpleContentFilter SimpleLogger SizeLimit SocketIO SSI StackTrace Static Static::Minifier StaticShared Status Test::StashWarnings Throttle TMT UseChromeFrame Watermark
  • 122. Plack Middleware Wraps a PSGI application to add pre/post processing
  • 123.
  • 127. Logging Status code redirect Error Handler Cache Middleware
  • 128. Logging Status code redirect Error Handler Cache Middleware Session Middleware
  • 129. Logging Status code redirect Error Handler Cache Middleware Session Middleware Routes Middleware
  • 130. Logging Status code redirect Error Handler Cache Middleware Session Middleware Routes Middleware Your App
  • 131. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App
  • 132. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in
  • 133. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in P::MW::A
  • 134. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in P::MW::A P::MW::B
  • 135. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in P::MW::A P::MW::B PSGI App
  • 136. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in P::MW::A P::MW::B P::MW::B PSGI App
  • 137. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
  • 138. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in Response out P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
  • 139. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in e.g. Redirect Response out P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
  • 140. Plack::Middleware::A Plack::Middleware::B PSGI Compatible App Request in e.g. Redirect Response out P::MW::A P::MW::A e.g. Static P::MW::B P::MW::B PSGI App
  • 141. Enabling Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
  • 142. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; enable “B”; $app; }
  • 143. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; enable “B”; $app; }
  • 144. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; enable “B”; $app; }
  • 145. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; enable “B”; $app; }
  • 146. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; # Plack::Middleware::A enable “B”; # Order matters $app; }
  • 147. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “A”; enable “B”; $app; }
  • 148. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app; }
  • 149. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app; }
  • 150. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app; }
  • 151. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app; }
  • 152. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App
  • 153. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in
  • 154. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Static
  • 155. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static
  • 156. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static -
  • 157. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static - PSGI App
  • 158. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static - Deflate compresses PSGI App
  • 159. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static - - Deflate compresses PSGI App
  • 160. Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App Request in Response out =~ ^/static Static - - Deflate compresses PSGI App
  • 161. plackup compatible plackup -e ‘enable “Foo”;’ app.psgi
  • 162. Middleware Write once, run in every framework
  • 164. Assume... use Plack::Builder; my $body = ‘<html><body>Hello World</body></html>’; my $app = sub { my $self = shift; return [200, ['Content-Type' => 'text/html'], [ $body ]]; };
  • 165. Assume... use Plack::Builder; my $body = ‘<html><body>Hello World</body></html>’; my $app = sub { my $self = shift; return [200, ['Content-Type' => 'text/html'], [ $body ]]; };
  • 166. Assume... use Plack::Builder; my $body = ‘<html><body>Hello World</body></html>’; my $app = sub { my $self = shift; return [200, ['Content-Type' => 'text/html'], [ $body ]]; };
  • 168. return builder { # Precious debug info. Right on your page! enable 'Debug'; $app; }
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 178. my $app = sub { my $foo = 'bar'; die "oops" if $foo eq 'bar'; [200, ['Content-Type' => 'text/html'], [ $body ]]; }; return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app; }
  • 179. my $app = sub { my $foo = 'bar'; die "oops" if $foo eq 'bar'; [200, ['Content-Type' => 'text/html'], [ $body ]]; }; return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app; }
  • 180. my $app = sub { my $foo = 'bar'; die "oops" if $foo eq 'bar'; [200, ['Content-Type' => 'text/html'], [ $body ]]; }; return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app; }
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 188. First rule of Program Optimisation
  • 190. Second rule of Program Optimisation (for experts only)
  • 191. Don’t do it - yet!
  • 192. return builder { enable 'Debug', panels => [ [ 'Profiler::NYTProf' ] ]; $app; };
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 199. use Plack::Builder; return builder { enable "ServerStatus::Lite", path => '/server-status', allow => [ '127.0.0.1'], scoreboard => '/tmp/score'; $app; }
  • 200.
  • 201.
  • 202.
  • 203.
  • 205. use Plack::Builder; return builder { enable "SizeLimit", max_unshared_size_in_kb => 3000, check_every_n_requests => 5; $app; }
  • 207.
  • 208. Apache::ActionWrapper CGIBin Cascade CocProxy DAV Directory Directory::Xslate FCGIDispatcher File ImageMagick JSP PSGIBin Path::Router Proxy Proxy::Backend::AnyEvent::HTTP Proxy::Backend::LWP Proxy::Selective Proxy::Test URLMap WrapApacheReq WrapApacheReq::FakeRequest WrapCGI
  • 211. Plack::App::Directory Static content file server
  • 212. Plack::App::Proxy (non-blocking) proxy server Can be used as reverse proxy as well
  • 214. # app.psgi - Javascript! Plack::App::JSP->new( js => q{ function respond(body) { return [ 200, [ 'Content-type', 'text/html' ], [ body ] ] } respond("Five factorial is " + (function(x) { if ( x<2 ) return x; return x * arguments.callee(x - 1); })(5) ); });
  • 215. # app.psgi - Javascript! Plack::App::JSP->new( js => q{ function respond(body) { return [ 200, [ 'Content-type', 'text/html' ], [ body ] ] } respond("Five factorial is " + (function(x) { if ( x<2 ) return x; return x * arguments.callee(x - 1); })(5) ); });
  • 216. Plack::App::URLMap Multiplex multiple apps Integrated with Builder DSL
  • 217. use CatApp; use CGIApp; my $c1 = sub { CatApp->run }; my $c2 = sub { CGIApp->run_psgi }; use Plack::Builder; return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; }; }
  • 218. use CatApp; use CGIApp; my $c1 = sub { CatApp->run }; my $c2 = sub { CGIApp->run_psgi }; use Plack::Builder; return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; }; }
  • 219. use CatApp; use CGIApp; my $c1 = sub { CatApp->run }; my $c2 = sub { CGIApp->run_psgi }; use Plack::Builder; return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; }; }
  • 222. TemplateToolkit + Static
  • 223. my $root = '/path/to/html_doc_root'; my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root, )->to_app; return builder { enable 'Static', path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app; }
  • 224. my $root = '/path/to/html_doc_root'; my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root, )->to_app; return builder { enable 'Static', path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app; }
  • 225. my $root = '/path/to/html_doc_root'; my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root, )->to_app; return builder { enable 'Static', path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app; }
  • 226. my $root = '/path/to/html_doc_root'; my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root, )->to_app; return builder { enable 'Static', path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app; }
  • 227. my $root = '/path/to/html_doc_root'; my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root, )->to_app; return builder { enable 'Static', path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app; }
  • 233. Slow website Website Developing code
  • 235. Slow website Caching Proxy Developing code
  • 236. use Plack::Middleware::Cache; use Plack::App::Proxy; my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; return builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache'; $app; };
  • 237. use Plack::Middleware::Cache; use Plack::App::Proxy; my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; return builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache'; $app; };
  • 238. use Plack::Middleware::Cache; use Plack::App::Proxy; my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; return builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache'; $app; };
  • 239.
  • 240.
  • 241.
  • 242. use LWP::Simple; my $content = get(‘http://localhost:5000/’);
  • 243. Caching Proxy + Domain hijack
  • 244. use LWP::Simple; my $content = get(‘http://localhost:5000/’);
  • 245. use LWP::Simple; my $content = get(‘http://london.pm.org/’);
  • 246. my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; return builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache2'; $app; };
  • 247. my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; return builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache2'; $app; };
  • 248. my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app; $app = builder { enable "Cache", match_url => '^/.*', # everything cache_dir => '/tmp/plack-cache2'; $app; };
  • 249. # Hijack Any LWP::Useragent requests LWP::Protocol::PSGI->register($app); use LWP::Simple; my $content = get("http://london.pm.org/"); say 'o/' if $content =~ /London Perl Mongers/;
  • 250. # Hijack Any LWP::Useragent requests LWP::Protocol::PSGI->register($app); use LWP::Simple; my $content = get("http://london.pm.org/"); say 'o/' if $content =~ /London Perl Mongers/;
  • 251. # Hijack Any LWP::Useragent requests LWP::Protocol::PSGI->register($app); use LWP::Simple; my $content = get("http://london.pm.org/"); say 'o/' if $content =~ /London Perl Mongers/;
  • 252. # Hijack Any LWP::Useragent requests LWP::Protocol::PSGI->register($app); use LWP::Simple; my $content = get("http://london.pm.org/"); say 'o/' if $content =~ /London Perl Mongers/;
  • 253.
  • 254.
  • 255.
  • 256. Plack::Test Unified interface to write TAP tests with Mock HTTP and Live HTTP
  • 257. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 258. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 259. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 260. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 261. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 262. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 263. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 264. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
  • 266. use Test::WWW::Mechanize::PSGI;   my $mech = Test::WWW::Mechanize::PSGI->new(      app => $app, ); $mech->get_ok('/');
  • 267. use Test::WWW::Mechanize::PSGI;   my $mech = Test::WWW::Mechanize::PSGI->new(      app => $app, ); $mech->get_ok('/');
  • 268. Testing your full configuration!
  • 270. Use a reverse proxy
  • 271. Use a reverse proxy • Sits in front of servers, not clients - “reverse”
  • 272. Use a reverse proxy • Sits in front of servers, not clients - “reverse” • Makes servers more efficient
  • 273. Use a reverse proxy • Sits in front of servers, not clients - “reverse” • Makes servers more efficient • Add HTTPS easily
  • 274. Use a reverse proxy • Sits in front of servers, not clients - “reverse” • Makes servers more efficient • Add HTTPS easily • Makes scaling easier
  • 279. Internet / Users Reverse Proxy NGINX Perlbal Pound Webserver App
  • 280. Internet / Users Reverse Proxy NGINX Perlbal Pound Webserver App
  • 281. Internet / Users Reverse Proxy NGINX Perlbal Pound Webserver App
  • 282. Internet / Users Reverse Proxy NGINX Perlbal Pound Webserver App
  • 283. Internet / Users Reverse Proxy NGINX Perlbal Pound Webserver App
  • 284. Reverse Proxy NGINX Perlbal Pound Server
  • 285. Reverse Proxy NGINX Perlbal Pound Server 1 Server 2
  • 286. Reverse Proxy NGINX Perlbal Pound Server 1 Server 3 Server 2
  • 287. Reverse Proxy NGINX Perlbal Pound Server 1 Server 3 Server 2
  • 288. Plack::Middleware::ReverseProxy Updates $env->{REMOTE_ADDRESS}
  • 290. Why use Plack? ‣ Flexibility ‣ Middleware ‣ Apps ‣ Development ‣ Testing ‣ Deployment
  • 291. Flexibility Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc
  • 292. Flexibility • Easy to change webserver (25+!) Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc
  • 293. Flexibility • Easy to change webserver (25+!) Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc • Starman seems to be used most
  • 295. Middleware • Easy to reuse with any PSGI app
  • 296. Middleware • Easy to reuse with any PSGI app • Many tools to make your life easy
  • 297. Middleware • Easy to reuse with any PSGI app • Many tools to make your life easy • 160+ on CPAN now
  • 298. App
  • 300. App • URLMapping / Routing • Static files
  • 301. App • URLMapping / Routing • Static files • Proxying
  • 304. Development • plackup • Restarter (monitor changes on disk)
  • 305. Development • plackup • Restarter (monitor changes on disk) • HTTP::Server::PSGI
  • 306. Development • plackup • Restarter (monitor changes on disk) • HTTP::Server::PSGI • Debugging middleware
  • 307. Development • plackup • Restarter (monitor changes on disk) • HTTP::Server::PSGI • Debugging middleware • Profiler
  • 309. Testing • Testing your full configuration
  • 310. Testing • Testing your full configuration • Test::WWW::Mechanize::PSGI
  • 311. Testing • Testing your full configuration • Test::WWW::Mechanize::PSGI • Plack::Test
  • 313. Deployment • No separate configuration files
  • 314. Deployment • No separate configuration files • Easy to choose/change webserver
  • 315. Deployment • No separate configuration files • Easy to choose/change webserver • DotCloud etc - cloud deployment
  • 317. Summary ✦ PSGI is an interface, Plack is the code.
  • 318. Summary ✦ PSGI is an interface, Plack is the code. ✦ Many fast PSGI servers.
  • 319. Summary ✦ PSGI is an interface, Plack is the code. ✦ Many fast PSGI servers. ✦ Adapters and tools for frameworks and webservers.
  • 320. Summary ✦ PSGI is an interface, Plack is the code. ✦ Many fast PSGI servers. ✦ Adapters and tools for frameworks and webservers. ✦ An amazing amount of middleware
  • 321. Summary ✦ PSGI is an interface, Plack is the code. ✦ Many fast PSGI servers. ✦ Adapters and tools for frameworks and webservers. ✦ An amazing amount of middleware ✦ Used in many production systems
  • 323. Thank you! Slides: http://slideshare.net/ranguard http://plackperl.org/ irc://irc.perl.org/#plack