YAPC::Asia 2009                     2009/09/10




                 dann
          techmemo@gmail.com

Angelos           github.com/dann          dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
request
            Engine                                    response
                                              (                  with Plack)
                                                  miyagawa++, tokuhirom++



                                                    Component
          Dispatcher                                 Manager
            URL to Controller
                                                     Component load & search
Angelos                         github.com/dann                                dann
Angelos   github.com/dann   dann
sub build_engine {
  my $self         = shift;
  my $request_handler = $self->request_handler;
  $request_handler ||= $self->build_request_handler;
    return Angelos::PSGI::Engine->new(
       interface => {                    Server Gateway
          module => $self->server,
          ....
       },
       psgi_handler => $request_handler,
    );                            Server Gateway
}
                                           psgi handler
Angelos                  github.com/dann                  dann
use Mouse;
use Angelos::Types qw( ServerGateway );
 
has 'interface' => (
                                     Server Gateway
    is => 'ro',
    isa => ServerGateway,
    coerce => 1,
);                                          Server Gateway
                                          psgi handler (coderef)
has 'psgi_handler' => ( is => 'rw', );
 
sub run {
    my $self = shift;
    $self->interface->run( $self->psgi_handler );
}
 Angelos                   github.com/dann                     dann
package Angelos::PSGI::ServerGatewayBuilder;
use strict;
use warnings;
use Plack::Loader;                 Plack::Loader
                                     ServerGateway
sub build {
  my ( $class, $module, $args ) = @_;
  my $server_gateway = Plack::Loader->load( $module,
%{$args} );
  $server_gateway;
}

 Angelos                 github.com/dann             dann
PSGI   env

...                               WAF Request
sub {                            (with Plack::Request)
          my $env = shift;
          my $req = Angelos::Request->new($env);
          my $res = $self->handle_request($req);
          my $psgi_res = $self->finalize_response($res);
          return $psgi_res;
}
...                      PSGI   response



Angelos                   github.com/dann                 dann
sub handle_request {                         req Dsipatcher
  my ( $self, $req ) = @_;
      eval { $self->DISPATCH($req); };
      if ( my $e = Exception::Class->caught() ) {
          $self->HANDLE_EXCEPTION($e);
      }
      # response
      return $self->context->res;
}

    Angelos                github.com/dann                    dann
request Dispatcher
sub DISPATCH {
  my ( $self, $req ) = @_;               dispatch

    my $dispatch = $self->dispatcher->dispatch($req);
    ...
    # dispatch
    $dispatch->run;
    # response
    $c->res;
}

Angelos                github.com/dann                       dann
<URL to Controller>
sub dispatch {                           HTTP::Router request
  my ( $self, $request ) = @_;                      route
                                         (ikasam_a++)
  my $match = $self->router->match($request);

  my $dispatch = $self->dispatch_class->new( match =>
$match );
  return $dispatch;
}                                   dispatch



Angelos                github.com/dann                        dann
# matching         controller
my $controller = $match->params->{controller};
my $controller_instance = $self-
>find_controller_instance(                Component Manager
    { context => $c,                      Controller
      controller => $controller,
    }
);                                       Controller action
...
$controller_instance->_dispatch_action( $action,
$params );

 Angelos               github.com/dann                       dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
sub _dispatch_action {
  my ( $self, $action, $params ) = @_; Hook
  ...
      eval { $self->ACTION( $self->context, $action, $params ); };
      ...
}




    Angelos                   github.com/dann                        dann
before 'ACTION' => sub {
   my ( $self, $c, $action, $params ) = @_;
   $self->__action_start_time( time() );
};
after 'ACTION' => sub {
   my ( $self, $c, $action, $params ) = @_;
   $self->__action_end_time( time() );
   my $elapsed = $self->__action_end_time - $self-
>__action_start_time;
   my $message
      = "action processing time:naction: $action ntime : $elapsed
secsn";
   $self->log->info($message);
};


 Angelos                    github.com/dann                      dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann

優しいWAFの作り方

  • 1.
    YAPC::Asia 2009 2009/09/10 dann techmemo@gmail.com Angelos github.com/dann dann
  • 2.
    Angelos github.com/dann dann
  • 3.
    Angelos github.com/dann dann
  • 4.
    Angelos github.com/dann dann
  • 5.
    Angelos github.com/dann dann
  • 6.
    request Engine response ( with Plack) miyagawa++, tokuhirom++ Component Dispatcher Manager URL to Controller Component load & search Angelos github.com/dann dann
  • 7.
    Angelos github.com/dann dann
  • 8.
    sub build_engine { my $self = shift; my $request_handler = $self->request_handler; $request_handler ||= $self->build_request_handler; return Angelos::PSGI::Engine->new( interface => { Server Gateway module => $self->server, .... }, psgi_handler => $request_handler, ); Server Gateway } psgi handler Angelos github.com/dann dann
  • 9.
    use Mouse; use Angelos::Typesqw( ServerGateway );   has 'interface' => ( Server Gateway     is => 'ro',     isa => ServerGateway,     coerce => 1, ); Server Gateway   psgi handler (coderef) has 'psgi_handler' => ( is => 'rw', );   sub run {     my $self = shift;     $self->interface->run( $self->psgi_handler ); } Angelos github.com/dann dann
  • 10.
    package Angelos::PSGI::ServerGatewayBuilder; use strict; usewarnings; use Plack::Loader; Plack::Loader ServerGateway sub build { my ( $class, $module, $args ) = @_; my $server_gateway = Plack::Loader->load( $module, %{$args} ); $server_gateway; } Angelos github.com/dann dann
  • 11.
    PSGI env ... WAF Request sub { (with Plack::Request) my $env = shift; my $req = Angelos::Request->new($env); my $res = $self->handle_request($req); my $psgi_res = $self->finalize_response($res); return $psgi_res; } ... PSGI response Angelos github.com/dann dann
  • 12.
    sub handle_request { req Dsipatcher my ( $self, $req ) = @_; eval { $self->DISPATCH($req); }; if ( my $e = Exception::Class->caught() ) { $self->HANDLE_EXCEPTION($e); } # response return $self->context->res; } Angelos github.com/dann dann
  • 13.
    request Dispatcher sub DISPATCH{ my ( $self, $req ) = @_; dispatch my $dispatch = $self->dispatcher->dispatch($req); ... # dispatch $dispatch->run; # response $c->res; } Angelos github.com/dann dann
  • 14.
    <URL to Controller> subdispatch { HTTP::Router request my ( $self, $request ) = @_; route (ikasam_a++) my $match = $self->router->match($request); my $dispatch = $self->dispatch_class->new( match => $match ); return $dispatch; } dispatch Angelos github.com/dann dann
  • 15.
    # matching controller my $controller = $match->params->{controller}; my $controller_instance = $self- >find_controller_instance( Component Manager { context => $c, Controller controller => $controller, } ); Controller action ... $controller_instance->_dispatch_action( $action, $params ); Angelos github.com/dann dann
  • 16.
    Angelos github.com/dann dann
  • 17.
    Angelos github.com/dann dann
  • 18.
    Angelos github.com/dann dann
  • 19.
    Angelos github.com/dann dann
  • 20.
    Angelos github.com/dann dann
  • 21.
    Angelos github.com/dann dann
  • 22.
    Angelos github.com/dann dann
  • 23.
    sub _dispatch_action { my ( $self, $action, $params ) = @_; Hook ... eval { $self->ACTION( $self->context, $action, $params ); }; ... } Angelos github.com/dann dann
  • 24.
    before 'ACTION' =>sub { my ( $self, $c, $action, $params ) = @_; $self->__action_start_time( time() ); }; after 'ACTION' => sub { my ( $self, $c, $action, $params ) = @_; $self->__action_end_time( time() ); my $elapsed = $self->__action_end_time - $self- >__action_start_time; my $message = "action processing time:naction: $action ntime : $elapsed secsn"; $self->log->info($message); }; Angelos github.com/dann dann
  • 25.
    Angelos github.com/dann dann
  • 26.
    Angelos github.com/dann dann
  • 27.
    Angelos github.com/dann dann