package Dancer::Handler::PSGI; use strict; use warnings; use Carp; use base 'Dancer::Handler'; use Dancer::Deprecation; use Dancer::GetOpt; use Dancer::Config; use Dancer::ModuleLoader; use Dancer::SharedData; use Dancer::Logger; use Dancer::Exception qw(:all); sub new { my $class = shift; raise core_handler_PSGI => "Plack::Request is needed by the PSGI handler" unless Dancer::ModuleLoader->load('Plack::Request'); my $self = {}; bless $self, $class; } sub start { my $self = shift; my $app = $self->psgi_app(); foreach my $setting (qw/plack_middlewares plack_middlewares_map/) { if (Dancer::Config::setting($setting)) { my $method = 'apply_'.$setting; $app = $self->$method($app); } } return $app; } sub apply_plack_middlewares_map { my ($self, $app) = @_; my $mw_map = Dancer::Config::setting('plack_middlewares_map'); foreach my $req (qw(Plack::App::URLMap Plack::Builder)) { raise core_handler_PSGI => "$req is needed to use apply_plack_middlewares_map" unless Dancer::ModuleLoader->load($req); } my $urlmap = Plack::App::URLMap->new; while ( my ( $path, $mw ) = each %$mw_map ) { my $builder = Plack::Builder->new(); $builder->add_middleware(@$_) for @$mw; $urlmap->map( $path => $builder->to_app($app) ); } $urlmap->map('/' => $app) unless $mw_map->{'/'}; return $urlmap->to_app; } sub apply_plack_middlewares { my ($self, $app) = @_; my $middlewares = Dancer::Config::setting('plack_middlewares'); raise core_handler_PSGI => "Plack::Builder is needed for middlewares support" unless Dancer::ModuleLoader->load('Plack::Builder'); ref $middlewares eq "ARRAY" or raise core_handler_PSGI => "'plack_middlewares' setting must be an ArrayRef"; my $builder = Plack::Builder->new(); for my $mw (@$middlewares) { Dancer::Logger::core "add middleware " . $mw->[0]; $builder->add_middleware(@$mw) } return $builder->to_app($app); } sub init_request_headers { my ($self, $env) = @_; my $plack = Plack::Request->new($env); Dancer::SharedData->headers($plack->headers); } 1; __END__ =pod =head1 NAME Dancer::Handler::PSGI - a PSGI handler for Dancer applications =head1 DESCRIPTION This handler allows Dancer applications to run as part of PSGI stacks. Dancer will automatically determine when running in a PSGI environment and enable this handler, such that calling C will return a valid PSGI application. You may enable Plack middleware in your configuration file under the C key. See L for more information. Note that you must have L installed for this handler to work. =head1 USAGE # in bin/app.pl set apphandler => 'Debug'; # then, run the app the following way perl -d bin/app.pl GET '/some/path/to/test' 'with=parameters&other=42' =head1 AUTHORS Dancer contributors