File Coverage

blib/lib/App/HTTPThis.pm
Criterion Covered Total %
statement 21 66 31.8
branch 0 30 0.0
condition 0 10 0.0
subroutine 7 11 63.6
pod 2 2 100.0
total 30 119 25.2


line stmt bran cond sub pod time code
1             package App::HTTPThis;
2             $App::HTTPThis::VERSION = '0.010';
3             # ABSTRACT: Export the current directory over HTTP
4              
5 1     1   203779 use strict;
  1         2  
  1         40  
6 1     1   3 use warnings;
  1         2  
  1         67  
7 1     1   500 use Plack::App::DirectoryIndex;
  1         174906  
  1         45  
8 1     1   578 use Plack::Runner;
  1         5179  
  1         35  
9 1     1   720 use Getopt::Long;
  1         11771  
  1         4  
10 1     1   711 use Pod::Usage;
  1         47426  
  1         128  
11 1     1   563 use Config::Tiny;
  1         1425  
  1         732  
12              
13              
14             sub new {
15 0     0 1   my $class = shift;
16 0           my $self = bless {port => 7007, root => '.'}, $class;
17              
18 0           my $default_config_file = '.http_thisrc';
19              
20 0 0         GetOptions(
21             $self, "help", "man", "config=s", "host=s", "port=i", "name=s", "autoindex", "pretty"
22             ) || pod2usage(2);
23 0 0         pod2usage(1) if $self->{help};
24 0 0         pod2usage(-verbose => 2) if $self->{man};
25              
26 0   0       my $config_file = $self->{config} || $ENV{HTTP_THIS_CONFIG};
27 0           for my $dir ('.', $ENV{HOME}) {
28 0 0 0       if (!$config_file && -f "$dir/$default_config_file") {
29 0           $config_file = "$dir/$default_config_file";
30 0           last;
31             }
32             }
33              
34 0 0         if ($config_file) {
35 0 0         my $config = Config::Tiny->read($config_file)
36             or die "FATAL: failed to read config file '$config_file'\n";
37 0           for my $key (qw(port name autoindex pretty)) {
38 0 0         $self->{$key} = $config->{_}->{$key} if $config->{_}->{$key};
39             }
40 0           delete $self->{config};
41             }
42              
43 0 0         if (@ARGV > 1) {
    0          
44 0           pod2usage("$0: Too many roots, only single root supported");
45             }
46             elsif (@ARGV) {
47 0           $self->{root} = shift @ARGV;
48             }
49              
50 0           return $self;
51             }
52              
53              
54             sub run {
55 0     0 1   my ($self) = @_;
56              
57 0           my $runner = Plack::Runner->new;
58             $runner->parse_options(
59             ($self->{host} ? ('--host' => $self->{host}) : ()),
60             '--port' => $self->{port},
61             '--env' => 'production',
62 0     0     '--server_ready' => sub { $self->_server_ready(@_) },
63 0 0         '--autoindex' => 0,
64             '--pretty' => 0,
65             );
66              
67             my $app_config = {
68             root => $self->{root},
69             pretty => $self->{pretty},
70 0           };
71 0 0         $app_config->{dir_index} = 'index.html' if $self->{autoindex};
72              
73 0           eval {
74 0           $runner->run(Plack::App::DirectoryIndex->new( $app_config )->to_app);
75             };
76 0 0         if (my $e = $@) {
77 0 0         die "FATAL: port $self->{port} is already in use, try another one\n"
78             if $e =~ /failed to listen to port/;
79 0           die "FATAL: internal error - $e\n";
80             }
81             }
82              
83             sub _server_ready {
84 0     0     my ($self, $args) = @_;
85              
86 0   0       my $host = $args->{host} || '127.0.0.1';
87 0   0       my $proto = $args->{proto} || 'http';
88 0           my $port = $args->{port};
89              
90 0           print "Exporting '$self->{root}', available at:\n";
91 0           print " $proto://$host:$port/\n";
92              
93 0 0         return unless my $name = $self->{name};
94              
95 0           eval {
96 0           require Net::Rendezvous::Publish;
97 0           Net::Rendezvous::Publish->new->publish(
98             name => $name,
99             type => '_http._tcp',
100             port => $port,
101             domain => 'local',
102             );
103             };
104 0 0         if ($@) {
105 0           print "\nWARNING: your server will not be published over Bonjour\n";
106 0           print " Install one of the Net::Rendezvous::Publish::Backend\n";
107 0           print " modules from CPAN\n"
108             }
109             }
110              
111             1;
112              
113             __END__