File Coverage

blib/lib/DiaColloDB/WWW/Handler.pm
Criterion Covered Total %
statement 14 54 25.9
branch 0 28 0.0
condition 0 17 0.0
subroutine 5 13 38.4
pod 7 8 87.5
total 26 120 21.6


line stmt bran cond sub pod time code
1             ##-*- Mode: CPerl -*-
2              
3             ## File: DiaColloDB::WWW::Handler.pm
4             ## Author: Bryan Jurish <moocow@cpan.org>
5             ## Description:
6             ## + abstract handler API class for DiaColloDB::WWW::Server
7             ## + adapted from DTA::CAB::Server::HTTP::Handler ( svn+ssh://odo.dwds.de/home/svn/dev/DTA-CAB/trunk/CAB/Server/HTTP/Handler.pm )
8             ##======================================================================
9              
10             package DiaColloDB::WWW::Handler;
11 1     1   6 use HTTP::Status;
  1         3  
  1         55  
12 1     1   292 use DiaColloDB::Logger;
  1         3  
  1         26  
13 1     1   487 use UNIVERSAL;
  1         12  
  1         4  
14 1     1   27 use strict;
  1         2  
  1         34  
15              
16             BEGIN {
17 1     1   3 *isa = \&UNIVERSAL::isa;
18 1         508 *can = \&UNIVERSAL::can;
19             }
20              
21             our @ISA = qw(DiaColloDB::Logger);
22              
23             ##======================================================================
24             ## API
25             ##======================================================================
26              
27             ## $h = $class_or_obj->new(%options)
28             sub new {
29 0     0 1   my $that = shift;
30 0   0       return bless { @_ }, ref($that)||$that;
31             }
32              
33             ## $bool = $h->prepare($server,$path)
34 0     0 0   sub prepare { return 1; }
35              
36             ## $rsp = $h->run($server, $clientConn, $httpRequest)
37             ## + perform local processing
38             ## + should return a HTTP::Response object to pass to the client
39             ## + if the call die()s or returns undef, an error response will be
40             ## sent to the client instead if it the connection is still open
41             ## + this method may return the data to the client itself; if so,
42             ## it should close the client connection ($csock->shutdown(2); $csock->close())
43             ## and return undef to prevent bogus error messages.
44             sub run {
45 0     0 1   my ($h,$srv,$csock,$hreq) = @_;
46 0           $h->logdie("run() method not implemented");
47             }
48              
49             ## undef = $h->finish($server, $clientConn)
50             ## + clean up handler state after run()
51             ## + default implementation does nothing
52             sub finish {
53 0     0 1   return;
54             }
55              
56             ##======================================================================
57             ## Generic Utilities
58              
59             ## $rsp = $h->headResponse()
60             ## $rsp = $h->headResponse(\@headers)
61             ## $rsp = $h->headResponse($httpHeaders)
62             ## + rudimentary handling for HEAD requests
63             sub headResponse {
64 0     0 1   my ($h,$hdr) = @_;
65 0           return $h->response(RC_OK,undef,$hdr);
66             }
67              
68             ## $rsp = $CLASS_OR_OBJECT->response($code=RC_OK, $msg=status_message($code), $hdr, $content)
69             ## + $hdr may be a HTTP::Headers object, an array or hash-ref
70             ## + wrapper for HTTP::Response->new()
71             sub response {
72 0     0 1   my $h = shift;
73 0           my $code = shift;
74 0 0         $code = RC_OK if (!defined($code));
75             ##
76 0 0         my $msg = @_ ? shift : undef;
77 0 0         $msg = status_message($code) if (!defined($msg));
78             ##
79 0 0         my $hdr = @_ ? shift : undef;
80 0 0         $hdr = [] if (!$hdr);
81             ##
82 0 0         return HTTP::Response->new($code,$msg,$hdr) if (!@_);
83 0           return HTTP::Response->new($code,$msg,$hdr,@_);
84             }
85              
86             ## undef = $h->cerror($csock, $status=RC_INTERNAL_SERVER_ERROR, @msg)
87             ## + sends an error response and sends it to the client socket
88             ## + also logs the error at level ($c->{logError}||'warn') and shuts down the socket
89             sub cerror {
90 0     0 1   my ($h,$c,$status,@msg) = @_;
91 0 0 0       if (defined($c) && $c->opened) {
92 0 0         $status = RC_INTERNAL_SERVER_ERROR if (!defined($status));
93 0           my $chost = $c->peerhost();
94 0 0         my $msg = @msg ? join('',@msg) : status_message($status);
95 0   0       $h->vlog(($h->{logError}||'error'), "client=$chost: $msg");
96             {
97 0           my $_warn=$^W;
  0            
98 0           $^W=0;
99 0           $c->send_error($status, $msg);
100 0           $^W=$_warn;
101             }
102 0           $c->shutdown(2);
103 0           $c->close();
104             }
105 0           return undef;
106             }
107              
108             ## $rsp = $h->dumpResponse(\$contentRef, %opts)
109             ## + Create and return a new data-dump response.
110             ## Known %opts:
111             ## (
112             ## raw => $bool, ##-- return raw data (text/plain) ; defualt=$h->{returnRaw}
113             ## type => $mimetype, ##-- mime type if not raw mode
114             ## charset => $enc, ##-- character set, if not raw mode
115             ## filename => $file, ##-- attachment name, if not raw mode
116             ## )
117             sub dumpResponse {
118 0     0 1   my ($h,$dataref,%vars) = @_;
119 0 0         my $returnRaw = defined($vars{raw}) ? $vars{raw} : $h->{returnRaw};
120 0 0 0       my $contentType = ($returnRaw || !$vars{type} ? 'text/plain' : $vars{type});
121 0 0 0       $contentType .= "; charset=$vars{charset}" if ($vars{charset} && $contentType !~ m|application/octet-stream|);
122             ##
123 0           my $rsp = $h->response(RC_OK);
124 0           $rsp->content_type($contentType);
125 0 0         $rsp->content_ref($dataref) if (defined($dataref));
126 0 0 0       $rsp->header('Content-Disposition' => "attachment; filename=\"$vars{filename}\"") if ($vars{filename} && !$returnRaw);
127 0           return $rsp;
128             }
129              
130              
131             1; ##-- be happy
132              
133             __END__