diff --git a/Makefile.PL b/Makefile.PL index 921241f..3186dfe 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -2,14 +2,8 @@ use inc::Module::Install; name 'PlackX-Engine'; all_from 'lib/PlackX/Engine.pm'; -requires( - -); -test_requires( - 'Test::More' => 0, - 'Test::Class' => 0, - 'Module::Install::AuthorTests' => 0, -); +requires( "Plack" => 0, ); +test_requires( 'Test::More' => 0, ); use_test_base; auto_include; WriteAll; diff --git a/config/example.psgi b/config/example.psgi new file mode 100644 index 0000000..c20eac7 --- /dev/null +++ b/config/example.psgi @@ -0,0 +1,27 @@ +use PlackX::Engine; +use Plack::Response; + +my $request_handler = sub { + my $req = shift; + my $res = Plack::Response->new; + $res->code(200); + $res->header( 'Content-Type' => 'text/html' ); + $res->body( ["Hello World"] ); + $res->finalize; +}; + +my $engine = PlackX::Engine->new( + { server => { + module => 'ServerSimple', + args => { + port => 3000, + host => 'localhost', + }, + }, + request_handler => $request_handler, + middlewares => + [ { module => "AccessLog::Timed" }, { module => "Static" } ], + } +); + +my $handler = $engine->handler; diff --git a/lib/PlackX/Engine.pm b/lib/PlackX/Engine.pm index f612949..349e22a 100644 --- a/lib/PlackX/Engine.pm +++ b/lib/PlackX/Engine.pm @@ -1,10 +1,68 @@ package PlackX::Engine; - use strict; use warnings; +use 5.008_001; our $VERSION = '0.01'; +use Class::Accessor "antlers"; +use Plack::Loader; +use Plack::Middleware; +use Plack::Builder; +use Plack::Request; + +has server => ( is => "rw", isa => "HashRef" ); +has request_handler => ( is => "rw", isa => "CodeRef" ); +has middlewares => ( is => "rw", isa => "ArrayRef" ); + +sub run { + my $self = shift; + my $server_instance + = $self->_build_server_instance( $self->{server}->{module}, + $self->{server}->{args} ); + my $request_handler = $self->handler; + $server_instance->run($request_handler); +} + +sub handler { + shift->_build_request_handler; +} + +sub _build_server_instance { + my ( $class, $server, $args ) = @_; + Plack::Loader->load( $server, %$args ); +} + +sub _build_request_handler { + my $self = shift; + my $request_handler = sub { + my $env = shift; + my $req = $self->build_request($env); + return $self->{request_handler}->($req); + }; + $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} || {} } ); + } + $request_handler; +} + +sub build_request { + my ( $self, $env ) = @_; + Plack::Request->new($env); +} + 1; + __END__ =encoding utf-8 @@ -16,12 +74,40 @@ PlackX::Engine - =head1 SYNOPSIS use PlackX::Engine; + use Plack::Response; + + my $request_handler = sub { + my $req = shift; + my $res = Plack::Response->new; + $res->code(200); + $res->header( 'Content-Type' => 'text/html' ); + $res->body( ["Hello World"] ); + $res->finalize; + }; + + my $engine = PlackX::Engine->new( + { + server => { + module => 'ServerSimple', + args => { + port => 3000, + host => 'localhost', + }, + }, + request_handler => $request_handler, + middlewares => [ + { module => "AccessLog::Timed" }, + { module => "Static" } + ], + } + ); + + $engine->run; =head1 DESCRIPTION PlackX::Engine is - =head1 SOURCE AVAILABILITY This source is in Github: diff --git a/t/00_load_all.t b/t/00_load_all.t index 6220991..3643555 100644 --- a/t/00_load_all.t +++ b/t/00_load_all.t @@ -2,6 +2,6 @@ use strict; use warnings; use Test::LoadAllModules; -BEGIN { +BEGIN { all_uses_ok(search_path => 'PlackX::Engine'); }