File Coverage

lib/Drogo/Dispatch.pm
Criterion Covered Total %
statement 43 48 89.5
branch 6 12 50.0
condition 10 22 45.4
subroutine 9 9 100.0
pod 0 1 0.0
total 68 92 73.9


line stmt bran cond sub pod time code
1             package Drogo::Dispatch;
2              
3 1     1   2488 use Exporter;
  1         2  
  1         39  
4 1     1   4 use strict;
  1         2  
  1         26  
5              
6 1     1   608 use Drogo::Guts;
  1         2  
  1         164  
7 1     1   496 use Drogo::Dispatcher;
  1         4  
  1         63  
8 1     1   518 use Drogo::Server::Test;
  1         3  
  1         114  
9              
10             # Configure exporter.
11             our @ISA = qw(Exporter Drogo::Dispatcher);
12             our @EXPORT = (@Nginx::Simple::HTTP_STATUS_CODES);
13              
14             our $VERSION = '0.03';
15              
16             =head1 NAME
17              
18             Drogo::Dispatch - Dispatching framework for Drogo
19              
20             For an example on using the dispatcher, please see L.
21              
22             use Drogo::Dispatch( auto_import => 1 );
23              
24             Parameters:
25              
26             import_drogo_methods - Inject methods from L into dispatched class, which is deprecated.
27             auto_import - Automatically load modules when they are dispatched, you probably do not want this in a production application.
28              
29             Mapping: Drogo can map to entirely different modules with the mapping hash.
30              
31             Example:
32              
33             use Drogo::Disaptch ( mapping => {
34             'tornado' => 'Tornado::App',
35             } );
36              
37             =cut
38              
39             sub import
40             {
41 1     1   9 my ($class, %params) = @_;
42 1   33     11 my $caller = $params{class} || caller;
43              
44             # inject a handler method
45             {
46 1     1   6 no strict 'refs';
  1         2  
  1         544  
  1         2  
47              
48 1         2 my $caller_isa = "$caller\::ISA";
49              
50 1         1 @{$caller_isa} = qw(
  1         18  
51             Drogo::Dispatcher
52             );
53              
54             # import_drogo_methods is deprecated
55 1 50       4 push @{$caller_isa}, 'Drogo::Guts'
  1         14  
56             if $params{import_drogo_methods};
57              
58 1         6 *{"$caller\::handler"} = sub {
59 15     15   50 my ($self, %custom_params) = @_;
60 15   33     61 my $server_obj = $custom_params{server} || $self;
61              
62 15         77 return local_dispatch(
63             $server_obj,
64             class => $caller,
65             app_path => $params{app_path},
66             auto_import => $params{auto_import},
67             auto_redirect => $params{auto_redirect},
68             mapping => $params{mapping},
69             %custom_params,
70             );
71 1         6 };
72             }
73              
74 1         105 __PACKAGE__->export_to_level(1, $class);
75             }
76              
77             # where do we dispatch to
78              
79             sub local_dispatch
80             {
81 15     15 0 84 my ($self, %params) = @_;
82 15         25 my $class = $params{class};
83 15   50     52 my $app_path = $params{app_path} || '';
84 15   33     34 my $path = $params{uri} || $self->uri;
85              
86             # self should be a server object, if it's not create a fake one
87 15 50       78 $self = Drogo::Server::Test->new(%params)
88             unless ref $self;
89              
90             # trip the app_path off $path, when applicable
91 15 50       35 $path =~ s/^$app_path// if $app_path;
92              
93 15         58 my $dispatch_data =
94             __PACKAGE__->dig_for_dispatch(
95             class => $class,
96             path => $path,
97             auto_import => $params{auto_import},
98             mapping => $params{mapping},
99             );
100              
101             # ensure indexes always end in a slash
102 15 0 33     40 if ($params{auto_redirect} and $dispatch_data->{index} and $path !~ /\/$/)
      33        
103             {
104 0         0 $self->status(302);
105 0         0 $self->header_out(Location => $self->uri . '/');
106 0         0 $self->send_http_header;
107              
108 0         0 return;
109             }
110              
111 15 100 66     56 if ($dispatch_data->{error} and $dispatch_data->{error} eq 'bad_dispatch')
    50          
112             {
113 2         9 return dispatch(
114             $self,
115             class => $class,
116             method => 'bad_dispatch',
117             bless => 1,
118             psgi => $params{psgi},
119             );
120             }
121             elsif ($dispatch_data->{error})
122             {
123 0         0 return dispatch(
124             $self,
125             class => $class,
126             method => 'error',
127             error => $dispatch_data->{error},
128             bless => 1,
129             psgi => $params{psgi},
130             );
131             }
132             else # prepare to dispatch for real
133             {
134 13   100     89 return dispatch(
135             $self,
136             class => $dispatch_data->{class},
137             method => $dispatch_data->{method},
138             base_class => $class,
139             dispatch_url => $dispatch_data->{dispatch_url},
140             bless => 1,
141             post_args => ($dispatch_data->{post_args} || [ ]),
142             psgi => $params{psgi},
143             );
144             }
145             }
146              
147             =head1 AUTHORS
148              
149             Bizowie
150              
151             =head1 COPYRIGHT AND LICENSE
152              
153             Copyright (C) 2013 Bizowie
154              
155             This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.
156              
157             =cut
158              
159             1;