File Coverage

blib/lib/Kossy/Connection.pm
Criterion Covered Total %
statement 26 59 44.0
branch 0 4 0.0
condition 0 16 0.0
subroutine 9 14 64.2
pod 0 9 0.0
total 35 102 34.3


line stmt bran cond sub pod time code
1             package Kossy::Connection;
2              
3 10     10   221955 use strict;
  10         45  
  10         313  
4 10     10   49 use warnings;
  10         19  
  10         418  
5             use Class::Accessor::Lite (
6 10         86 new => 1,
7             rw => [qw/req res stash args tx debug/]
8 10     10   1629 );
  10         3894  
9 10     10   8364 use JSON qw//;
  10         118607  
  10         286  
10 10     10   1353 use Kossy::Exception;
  10         20  
  10         6930  
11              
12             our $VERSION = '0.50';
13             my $_JSON = JSON->new()->allow_blessed(1)->convert_blessed(1)->ascii(1);
14              
15             # for IE7 JSON venularity.
16             # see http://www.atmarkit.co.jp/fcoding/articles/webapp/05/webapp05a.html
17             # Copy from Amon2::Plugin::Web::JSON => Fixed to escape only string parts
18             my %_ESCAPE = (
19             '+' => '\\u002b', # do not eval as UTF-7
20             '<' => '\\u003c', # do not eval as HTML
21             '>' => '\\u003e', # ditto.
22             );
23             sub escape {
24 0     0 0 0 my $self = shift;
25 0         0 my $body = shift;
26 0         0 $body =~ s!([+<>])!$_ESCAPE{$1}!g;
27 0         0 return qq("$body");
28             }
29             sub escape_json {
30 0     0 0 0 my $self = shift;
31 0         0 my $body = shift;
32             # escape only string parts
33 0         0 $body =~ s/"((?:\\"|[^"])*)"/$self->escape($1)/eg;
  0         0  
34 0         0 return $body;
35             }
36              
37             *request = \&req;
38             *response = \&res;
39              
40             sub env {
41 1     1 0 11 $_[0]->{req}->env;
42             }
43              
44             sub halt {
45 12     12 0 36790 my $self = shift;
46 12         62 die Kossy::Exception->new(@_);
47             }
48              
49             sub halt_text {
50 3     3 0 8371 my ($self, $code, $message) = @_;
51 3         16 $self->res->content_type('text/plain');
52 3         155 $self->res->body($message);
53 3         48 die Kossy::Exception->new($code, response => $self->res);
54             }
55              
56             sub halt_no_content {
57 2     2 0 4488 my ($self, $code) = @_;
58 2         7 $self->res->headers->remove_content_headers;
59 2         60 $self->res->content_length(0);
60 2         88 die Kossy::Exception->new($code, response => $self->res);
61             }
62              
63             sub redirect {
64 0     0 0   my $self = shift;
65 0           $self->res->redirect(@_);
66 0           $self->res;
67             }
68              
69             sub render {
70 0     0 0   my $self = shift;
71 0           my $file = shift;
72 0 0 0       my %args = ( @_ && ref $_[0] ) ? %{$_[0]} : @_;
  0            
73 0           my %vars = (
74             c => $self,
75             stash => $self->stash,
76             %args,
77             );
78              
79 0           my $body = $self->tx->render($file, \%vars);
80 0           $self->res->status( 200 );
81 0           $self->res->content_type('text/html; charset=UTF-8');
82 0           $self->res->body( $body );
83 0           $self->res;
84             }
85              
86             sub render_json {
87 0     0 0   my $self = shift;
88 0           my $obj = shift;
89              
90             # defense from JSON hijacking
91             # Copy from Amon2::Plugin::Web::JSON
92 0 0 0       if ( exists $self->req->env->{'HTTP_X_REQUESTED_WITH'} &&
      0        
      0        
      0        
      0        
93             ($self->req->env->{'HTTP_USER_AGENT'}||'') =~ /android/i &&
94             exists $self->req->env->{'HTTP_COOKIE'} &&
95             ($self->req->method||'GET') eq 'GET'
96             ) {
97 0           $self->halt(403,"Your request is maybe JSON hijacking.\nIf you are not a attacker, please add 'X-Requested-With' header to each request.");
98             }
99              
100 0           my $body = $_JSON->encode($obj);
101 0           $body = $self->escape_json($body);
102              
103 0           $self->res->status( 200 );
104 0           $self->res->content_type('application/json; charset=UTF-8');
105 0           $self->res->header( 'X-Content-Type-Options' => 'nosniff' ); # defense from XSS
106 0           $self->res->body( $body );
107 0           $self->res;
108             }
109              
110              
111              
112             1;
113