File Coverage

blib/lib/Kossy/Connection.pm
Criterion Covered Total %
statement 52 55 94.5
branch 2 4 50.0
condition 10 16 62.5
subroutine 12 13 92.3
pod 0 9 0.0
total 76 97 78.3


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