File Coverage

blib/lib/Dancer2/Core/Dispatcher.pm
Criterion Covered Total %
statement 31 31 100.0
branch 4 4 100.0
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 42 42 100.0


line stmt bran cond sub pod time code
1             package Dancer2::Core::Dispatcher;
2             # ABSTRACT: Class for dispatching request to the appropriate route handler
3             $Dancer2::Core::Dispatcher::VERSION = '2.0.1';
4 151     151   447450 use Moo;
  151         20242  
  151         1516  
5              
6 151     151   74532 use Dancer2::Core::Types;
  151         440  
  151         1594  
7 151     151   2256787 use Dancer2::Core::Request;
  151         388  
  151         5655  
8 151     151   99689 use Dancer2::Core::Response;
  151         716  
  151         64390  
9              
10             has apps => (
11             is => 'rw',
12             isa => ArrayRef,
13             default => sub { [] },
14             );
15              
16             has apps_psgi => (
17             is => 'ro',
18             isa => ArrayRef,
19             lazy => 1,
20             builder => '_build_apps_psgi',
21             );
22              
23             sub _build_apps_psgi {
24 35     35   547 my $self = shift;
25 35         373 return [ map +( $_->name, $_->to_app ), @{ $self->apps } ];
  35         856  
26             }
27              
28             sub dispatch {
29 132     132 1 59716 my ( $self, $env ) = @_;
30 132         300 my @apps = @{ $self->apps_psgi };
  132         4774  
31              
32 132         1763 DISPATCH: while (1) {
33 149         704 for ( my $i = 0; $i < @apps; $i += 2 ) {
34 191         1198 my ( $app_name, $app ) = @apps[ $i, $i + 1 ];
35              
36 191         815 my $response = $app->($env);
37              
38             # check for an internal request
39 191 100       12621 delete Dancer2->runner->{'internal_forward'}
40             and next DISPATCH;
41              
42             # the app raised a flag saying it couldn't match anything
43             # which is different than "I matched and it's a 404"
44             delete Dancer2->runner->{'internal_404'}
45 174 100       563 or do {
46 123         457 delete Dancer2->runner->{'internal_request'};
47 123         877 return $response;
48             };
49             }
50              
51             # don't run anymore
52 9         34 delete Dancer2->runner->{'internal_request'};
53 9         120 last;
54             } # while
55              
56             # a 404 on all apps, using the first app
57 9         281 my $default_app = $self->apps->[0];
58 9         97 my $request = $default_app->build_request($env);
59 9         38 return $default_app->response_not_found($request)->to_psgi;
60             }
61              
62             1;
63              
64             __END__