File Coverage

blib/lib/Plack/Middleware/JSON.pm
Criterion Covered Total %
statement 46 46 100.0
branch 10 14 71.4
condition 10 17 58.8
subroutine 9 9 100.0
pod 2 2 100.0
total 77 88 87.5


line stmt bran cond sub pod time code
1             package Plack::Middleware::JSON;
2 2     2   101771 use strict;
  2         4  
  2         72  
3 2     2   8 use warnings;
  2         2  
  2         49  
4 2     2   404 use parent qw/Plack::Middleware/;
  2         276  
  2         9  
5 2     2   12986 use JSON::XS;
  2         8601  
  2         104  
6 2     2   408 use URI::Escape;
  2         1038  
  2         136  
7             our $VERSION = 0.01;
8              
9 2     2   22 use Plack::Util::Accessor qw/json_key callback_key/;
  2         3  
  2         15  
10              
11             sub prepare_app {
12 4     4 1 2546 my $self = shift;
13 4 100       12 unless (defined $self->callback_key) {
14 3         81 $self->callback_key('callback');
15             }
16 4 100       27 if (defined $self->json_key) {
17 2         11 my $json_key = $self->json_key() . '|' . $self->callback_key;
18 2         12 $self->json_key($json_key);
19             }
20             else {
21 2         8 $self->json_key($self->callback_key);
22             }
23             }
24              
25             sub call {
26 4     4 1 46144 my($self, $env) = @_;
27 4         19 my $res = $self->app->($env);
28             $self->response_cb($res, sub {
29 4     4   48 my $res = shift;
30 4 50       10 if (defined $res->[2]) {
31 4         9 my $h = Plack::Util::headers($res->[1]);
32 4         67 my $json_key = $self->json_key;
33 4   50     30 my $content_type = $h->get('Content-Type') || '';
34 4 50 66     258 if (($json_key and $env->{QUERY_STRING} =~ /(?:^|&)($json_key)=([^&]+)/) or $content_type =~ m!/(?:json|javascript)!) {
      66        
35             # json
36 4 50 33     21 if ((ref $res->[2][0] eq 'ARRAY') or (ref $res->[2][0] eq 'HASH')) {
37 4         31 $res->[2] = [ encode_json($res->[2][0]) ];
38             }
39             # jsonp
40 4 100 33     15 if (defined $self->callback_key and $1 and $1 eq $self->callback_key) {
      100        
41 1         13 my $cb = URI::Escape::uri_unescape($2);
42 1 50       10 if ($cb =~ /^[\w\.\[\]]+$/) {
43 1         1 my $body;
44 1         6 Plack::Util::foreach($res->[2], sub { $body .= $_[0] });
  1         10  
45 1         4 my $jsonp = "$cb($body)";
46 1         3 $res->[2] = [ $jsonp ];
47             }
48             }
49 4         50 $h->set('Content-Length', length $res->[2][0]);
50 4         111 $h->set('Content-Type', 'application/json; charset=utf-8');
51             }
52             }
53 4         55 });
54             }
55              
56             1;
57             __END__