File Coverage

blib/lib/Github/Hooks/Receiver.pm
Criterion Covered Total %
statement 50 61 81.9
branch 14 20 70.0
condition 2 2 100.0
subroutine 11 12 91.6
pod 0 4 0.0
total 77 99 77.7


line stmt bran cond sub pod time code
1             package Github::Hooks::Receiver;
2 4     4   97442 use 5.008001;
  4         11  
  4         138  
3 4     4   16 use strict;
  4         4  
  4         112  
4 4     4   16 use warnings;
  4         14  
  4         166  
5              
6             our $VERSION = "0.03";
7              
8 4     4   1512 use Github::Hooks::Receiver::Event;
  4         20  
  4         114  
9              
10 4     4   2201 use JSON;
  4         36897  
  4         21  
11 4     4   2780 use Plack::Request;
  4         206361  
  4         233  
12             use Class::Accessor::Lite (
13 4         36 new => 1,
14             ro => [qw/secret/],
15 4     4   43 );
  4         6  
16              
17 24   100 24 0 185 sub events { shift->{events} ||= {} }
18              
19             sub to_app {
20 4     4 0 19 my $self = shift;
21              
22             my $app = sub {
23 9     9   85138 my $env = shift;
24 9         79 my $req = Plack::Request->new($env);
25 9 50       102 if ($req->method ne 'POST') {
26 0         0 return [400, [], ['BAD REQUEST']];
27             }
28              
29             # Parse JSON payload
30 9         86 my $payload_json;
31 9 100       38 if (lc $req->header('content-type') eq 'application/json') {
    100          
32 2         488 $payload_json = $req->content;
33             } elsif (lc $req->header('content-type') eq 'application/x-www-form-urlencoded') {
34 6         1418 $payload_json = $req->param('payload');
35             }
36 9 100       4436 my $payload = eval { decode_json $payload_json }
  9         107  
37             or return [400, [], ['BAD REQUEST']];
38              
39 8         28 my $event_name = $req->header('X-GitHub-Event');
40 8         339 my $event = Github::Hooks::Receiver::Event->new(
41             payload => $payload,
42             event => $event_name,
43             );
44              
45 8 50       78 if (my $code = $self->events->{''}) {
46 8         28 $code->($event, $req);
47             }
48 8 100       35 if (my $code = $self->events->{$event_name}) {
49 5         16 $code->($event, $req);
50             }
51              
52 8         144 [200, [], ['OK']];
53 4         21 };
54              
55 4 100       18 if ($self->secret) {
56 2         1494 require Plack::Middleware::HubSignature;
57 2         13482 $app = Plack::Middleware::HubSignature->wrap($app,
58             secret => $self->secret,
59             );
60             }
61 4         160 $app;
62             }
63              
64             sub on {
65 8     8 0 1150 my $self = shift;
66 8         15 my ($event, $code) = @_;
67 8 100       25 if (ref $event eq 'CODE') {
68 4         6 $code = $event;
69 4         8 $event = '';
70             }
71 8         20 $self->events->{$event} = $code;
72             }
73              
74             sub run {
75 0     0 0   my $self = shift;
76 0 0         my %opts = @_ == 1 ? %{$_[0]} : @_;
  0            
77              
78 0           my %server;
79 0           my $server = delete $opts{server};
80 0 0         $server{server} = $server if $server;
81              
82 0           my @options = %opts;
83 0           require Plack::Runner;
84              
85 0           my $runner = Plack::Runner->new(
86             %server,
87             options => \@options,
88             );
89 0           $runner->run($self->to_app);
90             }
91              
92             1;
93             __END__