File Coverage

blib/lib/Lim/RPC/Protocol/HTTP.pm
Criterion Covered Total %
statement 37 118 31.3
branch 0 34 0.0
condition 0 12 0.0
subroutine 13 17 76.4
pod 5 5 100.0
total 55 186 29.5


line stmt bran cond sub pod time code
1             package Lim::RPC::Protocol::HTTP;
2              
3 3     3   4647 use common::sense;
  3         7  
  3         31  
4              
5 3     3   346 use Scalar::Util qw(blessed weaken);
  3         9  
  3         257  
6              
7 3     3   19 use HTTP::Status qw(:constants);
  3         8  
  3         2459  
8 3     3   19 use HTTP::Request ();
  3         8  
  3         53  
9 3     3   16 use HTTP::Response ();
  3         6  
  3         64  
10 3     3   4563 use LWP::MediaTypes ();
  3         85854  
  3         195  
11 3     3   47 use Fcntl ();
  3         8  
  3         58  
12 3     3   19 use JSON::XS ();
  3         76  
  3         85  
13              
14 3     3   20 use Lim ();
  3         10  
  3         59  
15 3     3   18 use Lim::Util ();
  3         7  
  3         46  
16 3     3   20 use Lim::RPC::Callback ();
  3         6  
  3         78  
17              
18 3     3   19 use base qw(Lim::RPC::Protocol);
  3         6  
  3         6876  
19              
20             =encoding utf8
21              
22             =head1 NAME
23              
24             ...
25              
26             =head1 VERSION
27              
28             See L for version.
29              
30             =cut
31              
32             our $VERSION = $Lim::VERSION;
33             our $JSON = JSON::XS->new->ascii->convert_blessed;
34              
35             =head1 SYNOPSIS
36              
37             ...
38              
39             =head1 SUBROUTINES/METHODS
40              
41             =head2 Init
42              
43             =cut
44              
45 0     0 1 0 sub Init {
46             }
47              
48             =head2 Destroy
49              
50             =cut
51              
52 0     0 1 0 sub Destroy {
53             }
54              
55             =head2 name
56              
57             =cut
58              
59             sub name {
60 2     2 1 11 'http';
61             }
62              
63             =head2 serve
64              
65             =cut
66              
67 0     0 1   sub serve {
68             }
69              
70             =head2 handle
71              
72             =cut
73              
74             sub handle {
75 0     0 1   my ($self, $cb, $request) = @_;
76            
77 0 0 0       unless (blessed($request) and $request->isa('HTTP::Request')) {
78 0           return;
79             }
80            
81 0 0 0       unless (defined Lim::Config->{protocol}->{http}->{webroot}
82             and -d Lim::Config->{protocol}->{http}->{webroot})
83             {
84 0           return;
85             }
86              
87 0           my (@path, $path, $file);
88 0           foreach $path (split(/\//o, $request->uri->path)) {
89 0 0         if ($path eq '..') {
90 0 0         unless (scalar @path) {
91 0           return;
92             }
93 0           pop(@path);
94 0           next;
95             }
96 0 0         if ($path) {
97 0           push(@path, $path);
98             }
99             }
100              
101 0           $file = pop(@path);
102 0           $path = join('/', Lim::Config->{protocol}->{http}->{webroot}, @path);
103              
104 0 0         if (-d $path) {
105 0           my $response = HTTP::Response->new;
106 0           $response->request($request);
107 0           $response->protocol($request->protocol);
108            
109 0 0         unless (defined $file) {
110 0           $file = 'index.html';
111             }
112 0           $path .= '/'.$file;
113            
114 0 0         if (-d $path) {
115 0           $path .= '/index.html';
116             }
117            
118 0 0         unless (-r $path) {
119 0           return;
120             }
121              
122 0           my $query;
123 0 0         if ($request->header('Content-Type') =~ /(?:^|\s)application\/x-www-form-urlencoded(?:$|\s|;)/o) {
124 0           my $query_str = $request->content;
125 0           $query_str =~ s/[\015\012]+$//o;
126              
127 0           $query = Lim::Util::QueryDecode($query_str);
128             }
129             else {
130 0           $query = Lim::Util::QueryDecode($request->uri->query);
131             }
132            
133 0 0         Lim::DEBUG and $self->{logger}->debug('Serving file ', $path);
134              
135 0 0         unless (sysopen(FILE, $path, Fcntl::O_RDONLY)) {
136 0           $response->code(HTTP_FORBIDDEN);
137 0           $cb->cb->($response);
138 0           return 1;
139             }
140              
141 0           binmode(FILE);
142            
143 0           my ($size, $mtime) = (stat(FILE))[7,9];
144 0 0 0       unless (defined $size and defined $mtime) {
145 0           $response->code(HTTP_INTERNAL_SERVER_ERROR);
146 0           $cb->cb->($response);
147 0           return 1;
148             }
149            
150 0 0         if (defined $query->{jsonpCallback}) {
151 0           my ($content, $buf);
152 0           while (sysread(FILE, $buf, 64*1024)) {
153 0           $content .= $buf;
154             }
155 0           close(FILE);
156            
157 0           eval {
158 0           $content = $JSON->encode({ content => $content });
159             };
160 0 0         if ($@) {
161 0           $response->code(HTTP_INTERNAL_SERVER_ERROR);
162 0           $cb->cb->($response);
163 0           return 1;
164             }
165              
166 0           $response->header('Content-Type' => 'application/javascript; charset=utf-8');
167 0           $response->content($query->{jsonpCallback}.'('.$content.');');
168 0           $response->code(HTTP_OK);
169              
170 0           $cb->cb->($response);
171 0           return 1;
172             }
173            
174 0 0         unless (LWP::MediaTypes::guess_media_type($path, $response)) {
175 0           $response->code(HTTP_INTERNAL_SERVER_ERROR);
176 0           $cb->cb->($response);
177 0           return 1;
178             }
179              
180 0 0 0       if ($request->header('If-Modified-Since')
181             and $request->header('If-Modified-Since') >= $mtime)
182             {
183 0           close(FILE);
184 0           $response->code(HTTP_NOT_MODIFIED);
185 0           $cb->cb->($response);
186 0           return 1;
187             }
188              
189             $response->header(
190 0           'Content-Length' => $size,
191             'Last-Modified' => $mtime
192             );
193              
194 0           my $buf;
195 0           while (sysread(FILE, $buf, 64*1024)) {
196 0           $response->add_content($buf);
197             }
198 0           close(FILE);
199            
200 0           $response->code(HTTP_OK);
201              
202 0           $cb->cb->($response);
203 0           return 1;
204             }
205 0           return;
206             }
207              
208             =head1 AUTHOR
209              
210             Jerry Lundström, C<< >>
211              
212             =head1 BUGS
213              
214             Please report any bugs or feature requests to L.
215              
216             =head1 SUPPORT
217              
218             You can find documentation for this module with the perldoc command.
219              
220             perldoc Lim
221              
222             You can also look for information at:
223              
224             =over 4
225              
226             =item * Lim issue tracker (report bugs here)
227              
228             L
229              
230             =back
231              
232             =head1 ACKNOWLEDGEMENTS
233              
234             =head1 LICENSE AND COPYRIGHT
235              
236             Copyright 2012-2013 Jerry Lundström.
237              
238             This program is free software; you can redistribute it and/or modify it
239             under the terms of either: the GNU General Public License as published
240             by the Free Software Foundation; or the Artistic License.
241              
242             See http://dev.perl.org/licenses/ for more information.
243              
244              
245             =cut
246              
247             1; # End of Lim::RPC::Protocol::HTTP