File Coverage

blib/lib/HTML/WebDAO/Response.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 24 24 100.0


line stmt bran cond sub pod time code
1             #$Id: Lex.pm 106 2007-06-25 10:35:07Z zag $
2              
3             package HTML::WebDAO::Response;
4 1     1   3664 use Data::Dumper;
  1         3  
  1         59  
5 1     1   5 use HTML::WebDAO::Base;
  1         2  
  1         40  
6 1     1   796 use IO::File;
  1         11872  
  1         144  
7 1     1   3044 use DateTime;
  1         223307  
  1         48  
8 1     1   1185 use DateTime::Format::HTTP;
  1         7550  
  1         46  
9 1     1   12 use base qw( HTML::WebDAO::Base );
  1         3  
  1         181  
10             __PACKAGE__->attributes
11             qw/ __session _headers _is_headers_printed _cv_obj _is_file_send _is_need_close_fh __fh _is_flushed _call_backs/;
12             use strict;
13              
14             =head1 NAME
15              
16             HTML::WebDAO::Response - Response class
17              
18             =head1 SYNOPSIS
19              
20             use HTML::WebDAO;
21              
22             =head1 DESCRIPTION
23              
24             Class for set response headers
25              
26             =head1 METHODS
27              
28             =cut
29              
30             sub _init() {
31             my $self = shift;
32             return $self->init(@_);
33             }
34              
35             sub init {
36             my $self = shift;
37             my %par = @_;
38             $self->_headers( {} );
39             $self->_call_backs( [] );
40             $self->_cv_obj( $par{cv} );
41             $self->__session( $par{session} );
42             return 1;
43             }
44              
45             =head2 set_header NAME, VALUE
46              
47             Set out header:
48              
49             $response->set_header('Location', $redirect_url);
50             $response->set_header( -type => 'text/html; charset=utf-8' );
51              
52             return $self reference
53              
54             =cut
55              
56             sub set_header {
57             my ( $self, $name, $par ) = @_;
58              
59             # $self->_headers->{ $name =~ /^-/ ? uc $name : $name } = $par;
60             $self->_headers->{ uc $name } = $par;
61             $self;
62             }
63              
64             =head2 get_header NAME
65              
66             return value for header NAME:
67              
68             =cut
69              
70             sub get_header {
71             my ( $self, $name ) = @_;
72             return $self->_headers->{ uc $name };
73             }
74              
75             =head2 get_mime_for_filename
76              
77             Determine mime type for filename (Simple by ext);
78             return str
79              
80             =cut
81              
82             sub get_mime_for_filename {
83             my $self = shift;
84             my $filename = shift;
85             my %types_for_ext = (
86             avi => 'video/x-msvideo',
87             bmp => 'image/bmp',
88             css => 'text/css',
89             gif => 'image/gif',
90             gz => 'application/gzip',
91             html => 'text/html',
92             htm => 'text/html',
93             jpg => 'image/jpeg',
94             jpeg => 'image/jpeg',
95             js => 'application/javascript',
96             midi => 'audio/midi',
97             mp3 => 'audio/mpeg',
98             mpeg => 'video/mpeg',
99             mpg => 'video/mpeg',
100             mov => 'video/quicktime',
101             pdf => 'application/pdf',
102             png => 'image/png',
103             ppt => 'application/vnd.ms-powerpoint',
104             rtf => 'text/rtf',
105             tif => 'image/tif',
106             tiff => 'image/tif',
107             txt => 'text/plain',
108             xls => 'application/vnd.ms-excel',
109             xml => 'appliction/xml',
110             wav => 'audio/x-wav',
111             zip => 'application/zip',
112             );
113             my ($ext) = $filename =~ /\.(\w+)$/;
114             if ( my $type = $types_for_ext{ lc $ext } ) {
115             return $type;
116             }
117             return 'application/octet-stream';
118             }
119              
120             =head2 print_header
121              
122             print header.return $self reference
123              
124             =cut
125              
126             sub print_header {
127             my $self = shift;
128             my $pnted = $self->_is_headers_printed;
129             return $self if $pnted;
130             my $res = { data => '' }; #need for cv->response
131             my $cv = $self->_cv_obj;
132             my $headers = $self->_headers;
133             $headers->{-TYPE} = $res->{type} if $res->{type}; #deprecated
134             while ( my ( $key, $val ) = each %$headers ) {
135             my $UKey = uc $key;
136             $res->{headers}->{$UKey} = $headers->{$UKey}
137             unless exists $res->{headers}->{$UKey};
138             }
139             $cv->response($res);
140             $self->_is_headers_printed(1);
141             $self;
142             }
143              
144             =head2 redirect2url
145              
146             Set headers for redirect to url.return $self reference
147              
148             =cut
149              
150             sub redirect2url {
151             my ( $self, $redirect_url ) = @_;
152             $self->set_header( "-status", '302 Found' );
153             $self->set_header( '-Location', $redirect_url );
154             }
155              
156             =head2 set_cookie ( -name => , ...)
157              
158             Set cookie. For params see manpage for CGI::cookie.
159             return $self reference
160              
161             =cut
162              
163             sub set_cookie {
164             my $self = shift;
165             my $res = $self->get_header( -cookie ) || [];
166             my $cv = $self->_cv_obj;
167             push @$res, $cv->cookie(@_);
168             return $self->set_header( -cookie => $res );
169             }
170              
171             =head2 set_callback(sub1{}[, sub2{} ..])
172              
173             Set callbacks for call after flush
174              
175             =cut
176              
177             sub set_callback {
178             my $self = shift;
179             push @{ $self->_call_backs }, @_;
180             return $self;
181             }
182              
183             =head2 send_file || [, -type=>]
184              
185             Prepare headers and save
186              
187             $respose->send_file($filename, -type=>'image/jpeg');
188              
189             =cut
190              
191             sub send_file {
192             my $self = shift;
193             my $file = shift;
194             my %args = @_;
195             my $file_handle;
196             my $file_name;
197             if ( ref $file
198             and ( UNIVERSAL::isa( $file, 'IO::Handle' ) or ( ref $file ) eq 'GLOB' )
199             or UNIVERSAL::isa( $file, 'Tie::Handle' ) )
200             {
201             $file_handle = $file;
202             }
203             else {
204             $file_name = $file;
205             $file_handle = new IO::File::("< $file")
206             or die "can't open file: $file" . $!;
207             $self->_is_need_close_fh(1);
208             $self->__fh($file_handle);
209             }
210              
211             #set file headers
212             my ( $size, $mtime ) = ( stat $file_handle )[ 7, 9 ];
213             $self->set_header( '-Content_length', $size );
214             my $formated =
215             DateTime::Format::HTTP->format_datetime(
216             DateTime->from_epoch( epoch => $mtime ) );
217             $self->set_header( '-Last-Modified', $formated );
218              
219             #Determine mime tape of file
220             if ( my $predefined = $args{-type} ) {
221             $self->set_header( -type => $predefined );
222             }
223             else {
224             ##
225             if ($file_name) {
226             $self->set_header(
227             -type => $self->get_mime_for_filename($file_name) );
228             }
229             }
230             $self->_is_file_send(1);
231             $self;
232             }
233              
234             sub print {
235             my $self = shift;
236             my $cv = $self->_cv_obj;
237             $self->print_header;
238             $cv->print(@_);
239             return $self;
240             }
241              
242             sub _print_dep_on_context {
243             my ( $self, $session ) = @_;
244             my $res = $self->html;
245             $self->print( ref($res) eq 'CODE' ? $res->() : $res );
246             }
247              
248             =head2 flush
249              
250             Flush current state of response.
251              
252             =cut
253              
254             sub flush {
255             my $self = shift;
256             return $self if $self->_is_flushed;
257             $self->print_header;
258              
259             #do self print file
260             if ( $self->_is_file_send ) {
261             my $fd = $self->__fh;
262              
263             # open FH,">/tmp/DATA.jpg";
264             # print FH <$fd>;
265             # close FH;
266             $self->_cv_obj->print(<$fd>);
267              
268             # binmode ($fd);
269             # print <$fd>;
270             close($fd) if $self->_is_need_close_fh;
271             }
272             $self->_is_flushed(1);
273              
274             #do callbacks
275             my $ref_calls = $self->_call_backs;
276             while ( my $code = pop @$ref_calls ) {
277             $code->();
278             }
279              
280             #clear callbacks
281             @{ $self->_call_backs } = ();
282             $self;
283             }
284              
285             =head2 error404
286              
287             Set HTTP 404 headers
288              
289             =cut
290              
291             sub error404 {
292             my $self = shift;
293             $self->set_header( "-status", '404 Not Found' );
294             $self->print(@_) if @_;
295             return $self;
296             }
297              
298             sub html : lvalue {
299             my $self = shift;
300             $self->{__html};
301             }
302              
303             sub _destroy {
304             my $self = shift;
305             $self->{__html} = undef;
306             $self->auto( [] );
307             }
308             1;
309             __END__