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   83686 use 5.008001;
  4         10  
  4         119  
3 4     4   15 use strict;
  4         4  
  4         93  
4 4     4   13 use warnings;
  4         9  
  4         137  
5              
6             our $VERSION = "0.04";
7              
8 4     4   1215 use Github::Hooks::Receiver::Event;
  4         12  
  4         90  
9              
10 4     4   1733 use JSON;
  4         32141  
  4         16  
11 4     4   2238 use Plack::Request;
  4         150906  
  4         168  
12             use Class::Accessor::Lite (
13 4         39 new => 1,
14             ro => [qw/secret/],
15 4     4   62 );
  4         5  
16              
17 24   100 24 0 134 sub events { shift->{events} ||= {} }
18              
19             sub to_app {
20 4     4 0 18 my $self = shift;
21              
22             my $app = sub {
23 9     9   71779 my $env = shift;
24 9         51 my $req = Plack::Request->new($env);
25 9 50       68 if ($req->method ne 'POST') {
26 0         0 return [400, [], ['BAD REQUEST']];
27             }
28              
29             # Parse JSON payload
30 9         64 my $payload_json;
31 9 100       24 if (lc $req->header('content-type') eq 'application/json') {
    100          
32 2         291 $payload_json = $req->content;
33             } elsif (lc $req->header('content-type') eq 'application/x-www-form-urlencoded') {
34 6         1168 $payload_json = $req->param('payload');
35             }
36 9 100       3109 my $payload = eval { decode_json $payload_json }
  9         80  
37             or return [400, [], ['BAD REQUEST']];
38              
39 8         21 my $event_name = $req->header('X-GitHub-Event');
40 8         262 my $event = Github::Hooks::Receiver::Event->new(
41             payload => $payload,
42             event => $event_name,
43             );
44              
45 8 50       64 if (my $code = $self->events->{''}) {
46 8         24 $code->($event, $req);
47             }
48 8 100       28 if (my $code = $self->events->{$event_name}) {
49 5         19 $code->($event, $req);
50             }
51              
52 8         105 [200, [], ['OK']];
53 4         26 };
54              
55 4 100       17 if ($self->secret) {
56 2         808 require Plack::Middleware::HubSignature;
57 2         14325 $app = Plack::Middleware::HubSignature->wrap($app,
58             secret => $self->secret,
59             );
60             }
61 4         157 $app;
62             }
63              
64             sub on {
65 8     8 0 1287 my $self = shift;
66 8         10 my ($event, $code) = @_;
67 8 100       24 if (ref $event eq 'CODE') {
68 4         5 $code = $event;
69 4         7 $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__