File Coverage

blib/lib/Plack/Middleware/ModuleInfo.pm
Criterion Covered Total %
statement 58 65 89.2
branch 20 28 71.4
condition 4 9 44.4
subroutine 11 11 100.0
pod 2 2 100.0
total 95 115 82.6


line stmt bran cond sub pod time code
1             package Plack::Middleware::ModuleInfo;
2 2     2   23017 use strict;
  2         4  
  2         55  
3 2     2   11 use warnings;
  2         3  
  2         638  
4 2     2   784 use parent qw/Plack::Middleware/;
  2         332  
  2         14  
5 2     2   18510 use Plack::Util::Accessor qw/ path allow dumper /;
  2         4  
  2         14  
6 2     2   1814 use Net::CIDR::Lite;
  2         8530  
  2         62  
7 2     2   1576 use Module::Info;
  2         14097  
  2         1405  
8              
9             our $VERSION = '0.04';
10              
11             sub prepare_app {
12 4     4 1 5874 my $self = shift;
13              
14             # this code of block was copied from Plack::Middleware::ServerStatus::Lite ;-P
15 4 50       15 if ( $self->allow ) {
16 4 100       86 my @ip = ref $self->allow ? @{$self->allow} : ($self->allow);
  1         9  
17 4         38 my @ipv4;
18             my @ipv6;
19 4         10 for (@ip) {
20             # hacky check, but actual checks are done in Net::CIDR::Lite.
21 3 50       10 if (/:/) {
22 0         0 push @ipv6, $_;
23             } else {
24 3         9 push @ipv4, $_;
25             }
26             }
27 4 100       9 if ( @ipv4 ) {
28 3         18 my $cidr4 = Net::CIDR::Lite->new();
29 3         31 $cidr4->add_any($_) for @ipv4;
30 3         389 $self->{__cidr4} = $cidr4;
31             }
32 4 50       15 if ( @ipv6 ) {
33 0         0 my $cidr6 = Net::CIDR::Lite->new();
34 0         0 $cidr6->add_any($_) for @ipv6;
35 0         0 $self->{__cidr6} = $cidr6;
36             }
37             }
38              
39 4 50 33     14 if (!$self->allow || !$self->path) {
40 0         0 warn "[Plack::Middleware::ModuleInfo] 'allow' is not provided."
41             . "Any host will not be able to access the information.\n";
42             }
43              
44 4 50       52 unless ($self->dumper) {
45 4         741 require YAML;
46             $self->dumper(sub{
47 3     3   17 my ($info) = @_;
48             return [
49 3         14 200,
50             ['Content-Type' => 'text/plain'],
51             [YAML::Dump($info)]
52             ];
53 4         7460 });
54             }
55             }
56              
57             sub call {
58 5     5 1 29973 my ($self, $env) = @_;
59              
60 5         17 my $path = $self->path;
61              
62 5 100 66     76 if( $path && $env->{PATH_INFO} =~ m!^$path! ) {
63 4         14 my $res = $self->_handle_module_info($env);
64 4         23646 return $res;
65             }
66              
67 1         9 my $res = $self->app->($env);
68              
69 1         14 return $res;
70             }
71              
72             sub _handle_module_info {
73 4     4   6 my ($self, $env) = @_;
74              
75 4 100       14 if ( ! $self->_allowed($env->{REMOTE_ADDR}) ) {
76 1         20 return [403, ['Content-Type' => 'text/plain'], [ 'Forbidden' ]];
77             }
78              
79 3         234 my $info = { PID => $$, lib => \@INC, };
80              
81 3 100       11 if ( my $input_module = $env->{QUERY_STRING} ) {
82 2         7 $input_module =~ s/-/::/g;
83 2 100       14 if ( my $mod = Module::Info->new_from_loaded($input_module) ) {
84             $info->{module} = {
85 1   33     131 name => $mod->name,
86             version => eval "\$$input_module\::VERSION" || $mod->version, ## no critic
87             file => $mod->file,
88             };
89             }
90             else {
91 1         24 $info->{module} = "'$input_module' not found";
92             }
93             }
94              
95 3         24 return $self->dumper->($info, $env);
96             }
97              
98             sub _allowed {
99 4     4   7 my ( $self , $address ) = @_;
100              
101 4 50       11 if ( $address =~ /:/) {
102 0 0       0 return unless $self->{__cidr6};
103 0         0 return $self->{__cidr6}->find( $address );
104             }
105 4 100       14 return unless $self->{__cidr4};
106 3         17 return $self->{__cidr4}->find( $address );
107             }
108              
109             1;
110              
111             __END__