File Coverage

blib/lib/HTTP/Daemon/App.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package HTTP::Daemon::App;
2              
3 1     1   27004 use strict;
  1         3  
  1         43  
4 1     1   6 use warnings;
  1         2  
  1         30  
5              
6 1     1   1126 use version;our $VERSION = qv('0.0.9');
  1         2593  
  1         6  
7              
8 1     1   1122 use HTTP::Daemon;
  1         122153  
  1         12  
9 1     1   1321 use HTTP::Daemon::SSL;
  0            
  0            
10             use HTTP::Response;
11             use Acme::Spork;
12             use Unix::PID;
13             use File::Spec;
14              
15             use base 'Exporter';
16             our @EXPORT_OK = qw(run decode_basic_auth send_basic_auth_request);
17              
18             sub send_basic_auth_request {
19             my ($c, $realm) = @_;
20             $realm = 'Restricted Area' if !$realm;
21             my $auth_request_res = HTTP::Response->new(401, 'Unauthorized');
22             $auth_request_res->header('WWW-Authenticate' => qq{Basic realm="$realm"});
23             $auth_request_res->is_error(1);
24             $auth_request_res->error_as_HTML(1);
25             $c->send_response($auth_request_res);
26             }
27              
28             sub decode_basic_auth {
29             my ($auth) = @_;
30             no warnings 'uninitialized';
31             $auth = ( split /\s+/, $auth->header('Authorization') )[1] if ref $auth;
32             require MIME::Base64;
33             return split(/:/, MIME::Base64::decode( $auth ), 2);
34             }
35              
36             sub run {
37             my($daemons_hashref, $conf) = @_;
38            
39             $conf = {} if ref $conf ne 'CODE';
40             $conf->{'pid_dir'} = File::Spec->catdir(qw(/ var run)) if !$conf->{'pid_dir'};
41             $conf->{'pid_ext'} = '.pid' if !$conf->{'pid_ext'};
42             $conf->{'self'} = "perl $0" if !$conf->{'self'};
43            
44             my $additional = '';
45             for my $opt (sort keys %{ $conf->{'opts'} }) {
46             if($opt eq '--start' || $opt eq '--stop' || $opt eq '--restart') {
47             delete $conf->{'opts'}{$opt};
48             next;
49             }
50             $additional .= "|$opt";
51             }
52              
53             $ARGV[0] = '--help' if !defined $ARGV[0]; # no uninit warnings and logical visual clue to coders of what will happen if its not specified...
54             if($ARGV[0] eq '--restart') {
55             system qq($conf->{'self'} --stop $$);
56             sleep 1;
57             system qq($conf->{'self'} --start);
58             exit;
59             }
60            
61             if($ARGV[0] eq '--start') {
62             for my $daemon (sort keys %{ $daemons_hashref }) {
63             next if ref $daemons_hashref->{$daemon}{'handler'} ne 'CODE';
64             next if ref $daemons_hashref->{$daemon}{'daemon'} ne 'HASH';
65            
66             my $pidfile = File::Spec->catfile($conf->{'pid_dir'}, "$daemon$conf->{'pid_ext'}");
67            
68             my $objkt = $daemons_hashref->{$daemon}{'ssl'}
69             ? HTTP::Daemon::SSL->new( %{ $daemons_hashref->{$daemon}{'daemon'} } )
70             : HTTP::Daemon->new( %{ $daemons_hashref->{$daemon}{'daemon'} } )
71             ;
72             if(!$objkt) {
73             print "$daemon: $!\n";
74             next;
75             }
76              
77             print "Starting $daemons_hashref->{$daemon}{'label'}: url . ">\n"
78             if defined $daemons_hashref->{$daemon}{'label'};
79              
80             my $http_pid = spork(
81             sub {
82             my($handler, $d, $name, $pidfile, $conf) = @_;
83             local $0 = $name;
84             while (my $c = $d->accept) {
85             $conf->{'pre_fork'}->(@_) if ref $conf->{'pre_fork'} eq 'CODE';
86            
87             if(my $kid = fork()) {
88             $c->can('get_cipher') ? $c->close('SSL_no_shutdown' => 1) : $c->close;
89             undef($c);
90             }
91             else {
92             $conf->{'get_tmpfile'} = sub { return } if ref $conf->{'get_tmpfile'} ne 'CODE';
93             while (my $r = $c->get_request( $conf->{'get_tmpfile'}->( $conf ) )) {
94             $handler->($d, $c, $r, $conf);
95             }
96             # $c->can('get_cipher') ? $c->close('SSL_no_shutdown' => 1) : $c->close;
97             # undef($c);
98             exit 0;
99             }
100            
101             $conf->{'pst_fork'}->(@_) if ref $conf->{'pst_fork'} eq 'CODE';
102             }
103             }, $daemons_hashref->{$daemon}{'handler'}, $objkt, $daemon, $pidfile, $conf,
104             );
105              
106             Unix::PID->new()->pid_file_no_unlink($pidfile, $http_pid)
107             or die "The PID in $pidfile is still running.";
108             }
109             }
110             elsif($ARGV[0] eq '--stop') {
111             for my $daemon (sort keys %{ $daemons_hashref }) {
112             my $pidfile = File::Spec->catfile($conf->{'pid_dir'}, "$daemon$conf->{'pid_ext'}");
113              
114             my $uxp = Unix::PID->new();
115             my $pid = $uxp->kill_pid_file($pidfile);
116              
117             if($pid == 1) {
118             print "$daemon is not running\n";
119             }
120             elsif($pid eq '-1') {
121             print "$daemon pidfile: $!\n";
122             }
123             else {
124             print "$daemon ($pid) was stopped\n";
125             }
126              
127             print "\tCollecting $daemon children...\n";
128             for my $kid ($uxp->get_pidof($daemon) ) {
129             next if defined $ARGV[1] && $kid eq $ARGV[1];
130             $uxp->kill( $kid ) or print "\t\tCould not kill $daemon child $kid: $!\n";
131             }
132             }
133             }
134             elsif(exists $conf->{'opts'}{$ARGV[0]}) {
135             $conf->{'opts'}->{$ARGV[0]}->(@_);
136             }
137             else {
138             print "Useage: $0 [--start|--stop||--restart$additional]\n";
139             print "$conf->{'help'}\n" if $conf->{'help'};
140             }
141             }
142              
143             1;
144              
145             __END__