Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

build request handler with Builder.

  • Loading branch information...
commit ebb1395519c08f71f7c8bb82eca5d6cf04bfc4b4 1 parent 0701b26
@dann authored
View
4 config/example.psgi
@@ -7,7 +7,7 @@ my $request_handler = sub {
$res->code(200);
$res->header( 'Content-Type' => 'text/html' );
$res->body( ["Hello World"] );
- $res->finalize;
+ return $res;
};
my $engine = PlackX::Engine->new(
@@ -20,7 +20,7 @@ my $engine = PlackX::Engine->new(
},
request_handler => $request_handler,
middlewares =>
- [ { module => "AccessLog::Timed" }, { module => "Static" } ],
+ [ { module => "Plack::Middleware::AccessLog::Timed" }, { module => "Plack::Middleware::Static" } ],
}
);
View
44 lib/PlackX/Engine.pm
@@ -6,9 +6,8 @@ our $VERSION = '0.01';
use Class::Accessor "antlers";
use Plack::Loader;
-use Plack::Middleware;
-use Plack::Builder;
use Plack::Request;
+use PlackX::Engine::Builder;
has server => ( is => "rw", isa => "HashRef" );
has request_handler => ( is => "rw", isa => "CodeRef" );
@@ -33,27 +32,37 @@ sub _build_server_instance {
}
sub _build_request_handler {
- my $self = shift;
- my $request_handler = sub {
+ my $self = shift;
+ my $app = $self->_build_app;
+ $self->_wrap_with_middlewares($app);
+}
+
+sub _build_app {
+ my $self = shift;
+ return sub {
my $env = shift;
my $req = $self->build_request($env);
- return $self->{request_handler}->($req);
+ my $res = $self->{request_handler}->($req);
+ $res->finalize;
};
- $self->_wrap_with_middlewares($request_handler);
}
sub _wrap_with_middlewares {
my ( $self, $request_handler ) = @_;
- for my $middleware ( reverse @{ $self->{middlewares} || [] } ) {
- my $sub = $middleware->{module};
- my $subclass = $sub =~ s/^\+// ? $sub : "Plack::Middleware::$sub";
- eval "use $subclass";
- die $@ if $@;
-
- $request_handler = $subclass->wrap( $request_handler,
- %{ $middleware->{args} || {} } );
+ my $builder = PlackX::Engine::Builder->new;
+
+ # orz. this code should be moved to PlackX::Engine::Builder
+ for my $middleware ( @{ $self->{middlewares} || [] } ) {
+ my $middleware_name = $middleware->{module};
+ $builder->add_middleware(
+ $middleware_name,
+ sub {
+ $middleware_name->wrap( @{ $middleware->{args} || [] },
+ $_[0] );
+ }
+ );
}
- $request_handler;
+ $builder->to_app($request_handler);
}
sub build_request {
@@ -82,7 +91,6 @@ PlackX::Engine -
$res->code(200);
$res->header( 'Content-Type' => 'text/html' );
$res->body( ["Hello World"] );
- $res->finalize;
};
my $engine = PlackX::Engine->new(
@@ -96,8 +104,8 @@ PlackX::Engine -
},
request_handler => $request_handler,
middlewares => [
- { module => "AccessLog::Timed" },
- { module => "Static" }
+ { module => "Plack::Middleware::AccessLog::Timed" },
+ { module => "Plack::Middleware::Static" }
],
}
);
View
32 lib/PlackX/Engine/Builder.pm
@@ -0,0 +1,32 @@
+package PlackX::Engine::Builder;
+use strict;
+use warnings;
+use base qw/Class::Accessor::Fast/;
+__PACKAGE__->mk_accessors(qw/middlewares/);
+
+sub new {
+ my ( $class, $middlewares ) = @_;
+ $middlewares ||= [];
+ my $self = bless { middlewares => $middlewares }, $class;
+ return $self;
+}
+
+sub add_middleware {
+ my ( $self, $middleware_name, $middleware ) = @_;
+ eval "use $middleware_name";
+ die $@ if $@;
+
+ push @{ $self->{middlewares} }, $middleware;
+}
+
+sub to_app {
+ my ( $self, $app ) = @_;
+ for my $mw ( reverse @{ $self->{middlewares} } ) {
+ $app = $mw->($app);
+ }
+ $app;
+}
+
+1;
+
+__END__
View
39 lib/PlackX/Engine/Builder/Declare.pm
@@ -0,0 +1,39 @@
+package PlackX::Engine::Builder::Declare;
+use strict;
+use PlackX::Engine::Builder;
+
+sub import {
+ my $caller = caller;
+
+ no strict 'refs';
+ no warnings 'redefine';
+
+ *{ $caller . '::builder' } = \&builder;
+ *{ $caller . '::enable' } = \&enable;
+}
+
+sub builder(&) {
+ my $block = shift;
+
+ my $builder = PlackX::Engine::Builder->new;
+ no warnings 'redefine';
+
+ local *enable = enable_middleware($builder);
+
+ my $app = $block->();
+ $builder->to_app($app);
+}
+
+sub enable_middleware {
+ my $builder = shift;
+
+ return sub {
+ my ( $middleware, @args ) = @_;
+ $builder->add_middleware( $middleware,
+ sub { $middleware->wrap( @args, $_[0] ); } );
+ };
+}
+
+1;
+
+__END__
Please sign in to comment.
Something went wrong with that request. Please try again.