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.1.0';
4 155     155   363798 use Moo;
  155         12849  
  155         1313  
5              
6 155     155   71554 use Dancer2::Core::Types;
  155         446  
  155         1512  
7 155     155   2276125 use Dancer2::Core::Request;
  155         423  
  155         5595  
8 155     155   97971 use Dancer2::Core::Response;
  155         772  
  155         66126  
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 36     36   488 my $self = shift;
25 36         104 return [ map +( $_->name, $_->to_app ), @{ $self->apps } ];
  36         732  
26             }
27              
28             sub dispatch {
29 130     130 1 46228 my ( $self, $env ) = @_;
30 130         310 my @apps = @{ $self->apps_psgi };
  130         4894  
31              
32 130         1842 DISPATCH: while (1) {
33 147         714 for ( my $i = 0; $i < @apps; $i += 2 ) {
34 189         697 my ( $app_name, $app ) = @apps[ $i, $i + 1 ];
35              
36 189         814 my $response = $app->($env);
37              
38             # check for an internal request
39 189 100       12604 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 172 100       559 or do {
46 121         416 delete Dancer2->runner->{'internal_request'};
47 121         831 return $response;
48             };
49             }
50              
51             # don't run anymore
52 9         31 delete Dancer2->runner->{'internal_request'};
53 9         140 last;
54             } # while
55              
56             # a 404 on all apps, using the first app
57 9         293 my $default_app = $self->apps->[0];
58 9         97 my $request = $default_app->build_request($env);
59 9         39 return $default_app->response_not_found($request)->to_psgi;
60             }
61              
62             1;
63              
64             __END__