File Coverage

blib/lib/JSON/RPC2/AnyEvent/Server/PSGI.pm
Criterion Covered Total %
statement 48 50 96.0
branch 7 8 87.5
condition 2 3 66.6
subroutine 16 17 94.1
pod 0 1 0.0
total 73 79 92.4


line stmt bran cond sub pod time code
1             package JSON::RPC2::AnyEvent::Server::PSGI;
2 5     5   868755 use 5.008005;
  5         21  
  5         217  
3 5     5   32 use strict;
  5         8  
  5         162  
4 5     5   28 use warnings;
  5         18  
  5         255  
5              
6             our $VERSION = "0.01";
7              
8 5     5   1722 use AnyEvent;
  5         6306  
  5         197  
9 5     5   30 use JSON;
  5         10  
  5         30  
10 5     5   5712 use Plack::Request;
  5         3310128  
  5         183  
11 5     5   7166 use Try::Tiny;
  5         8337  
  5         345  
12              
13 5     5   10935 use JSON::RPC2::AnyEvent::Constants qw(ERR_PARSE_ERROR);
  5         3394  
  5         317  
14 5     5   4771 use JSON::RPC2::AnyEvent::Server;
  5         9192  
  5         2874  
15              
16              
17             sub JSON::RPC2::AnyEvent::Server::to_psgi_app {
18 4     4 0 439 my ($self) = @_;
19             sub{
20 19     19   447482 my $req = Plack::Request->new(shift);
21 19 100 66     291 if ( $req->method eq 'GET' or $req->method eq 'HEAD' ) {
    50          
22 5         81 return _dispatch_url_query($self, $req);
23             } elsif ( $req->method eq 'POST' ) {
24 14 100       422 return $req->content_type =~ m|^application/x-www-form-urlencoded$|i
25             ? _dispatch_url_query($self, $req)
26             : _dispatch_json($self, $req);
27             } else {
28 0         0 return [405, ['Content-type' => 'text/plain'], ['Method Not Allowed']]
29             }
30             }
31 4         23 }
32              
33             my $json = JSON->new->utf8;
34              
35             sub _dispatch_url_query {
36 11     11   77 my ($self, $req) = @_;
37 11         65 _dispatch_aux($self, {
38             jsonrpc => '2.0',
39             id => undef,
40             method => substr($req->path_info, 1),
41             params => $req->parameters->mixed,
42             });
43             }
44              
45             sub _dispatch_json {
46 8     8   81 my ($self, $req) = @_;
47             try{
48 8     8   742 my $hash = $json->decode($req->content);
49 8         9927 _dispatch_aux($self, $hash);
50             } catch {
51 0     0   0 [200, ['Content-Type', 'application/json'], [$json->encode({
52             jsonrpc => '2.0',
53             id => undef,
54             error => {code => ERR_PARSE_ERROR, message => 'Parse error', data => shift}
55             })]]
56 8         90 };
57             }
58              
59             sub _dispatch_aux {
60 19     19   5320 my ($self, $hash) = @_;
61 19         117 my $cv = $self->dispatch($hash);
62 19 100       28862 return [200, [], []] unless $cv; # notification
63             sub{
64 17     17   1171 my $writer = shift->([200, ['Content-Type', 'application/json']]);
65             $cv->cb(sub{
66 17         3968650 my $res = shift->recv;
67 17         591 $writer->write($json->encode($res));
68 17         3406654 $writer->close;
69 17         17730 });
70 17         193 };
71             }
72              
73              
74             1;
75             __END__