File Coverage

blib/lib/Plack/Middleware/ModuleInfo.pm
Criterion Covered Total %
statement 58 65 89.2
branch 20 28 71.4
condition 3 6 50.0
subroutine 11 11 100.0
pod 2 2 100.0
total 94 112 83.9


line stmt bran cond sub pod time code
1             package Plack::Middleware::ModuleInfo;
2 2     2   14578 use strict;
  2         3  
  2         64  
3 2     2   8 use warnings;
  2         2  
  2         57  
4 2     2   402 use parent qw/Plack::Middleware/;
  2         230  
  2         11  
5 2     2   11531 use Plack::Util::Accessor qw/ path allow dumper /;
  2         3  
  2         12  
6 2     2   1073 use Net::CIDR::Lite;
  2         5938  
  2         54  
7 2     2   962 use Module::Info;
  2         9599  
  2         972  
8              
9             our $VERSION = '0.02';
10              
11             sub prepare_app {
12 4     4 1 5861 my $self = shift;
13              
14             # this code of block was copied from Plack::Middleware::ServerStatus::Lite ;-P
15 4 50       14 if ( $self->allow ) {
16 4 100       92 my @ip = ref $self->allow ? @{$self->allow} : ($self->allow);
  1         5  
17 4         25 my @ipv4;
18             my @ipv6;
19 4         7 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         7 push @ipv4, $_;
25             }
26             }
27 4 100       11 if ( @ipv4 ) {
28 3         14 my $cidr4 = Net::CIDR::Lite->new();
29 3         29 $cidr4->add_any($_) for @ipv4;
30 3         369 $self->{__cidr4} = $cidr4;
31             }
32 4 50       13 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     9 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       41 unless ($self->dumper) {
45 4         431 require YAML;
46             $self->dumper(sub{
47 3     3   15 my ($info, $env) = @_;
48             return [
49 3         13 200,
50             ['Content-Type' => 'text/plain'],
51             [YAML::Dump($info)]
52             ];
53 4         5125 });
54             }
55             }
56              
57             sub call {
58 5     5 1 21812 my ($self, $env) = @_;
59              
60 5         16 my $path = $self->path;
61              
62 5 100 66     72 if( $path && $env->{PATH_INFO} =~ m!^$path! ) {
63 4         10 my $res = $self->_handle_module_info($env);
64 4         16007 return $res;
65             }
66              
67 1         27 my $res = $self->app->($env);
68              
69 1         16 return $res;
70             }
71              
72             sub _handle_module_info {
73 4     4   7 my ($self, $env) = @_;
74              
75 4 100       11 if ( ! $self->_allowed($env->{REMOTE_ADDR}) ) {
76 1         5 return [403, ['Content-Type' => 'text/plain'], [ 'Forbidden' ]];
77             }
78              
79 3         203 my $info = { PID => $$, lib => \@INC, };
80              
81 3 100       9 if ( my $input_module = $env->{QUERY_STRING} ) {
82 2         5 $input_module =~ s/-/::/g;
83 2 100       12 if ( my $mod = Module::Info->new_from_loaded($input_module) ) {
84 1         123 $info->{module} = {
85             name => $mod->name,
86             version => $mod->version,
87             file => $mod->file,
88             };
89             }
90             else {
91 1         25 $info->{module} = "'$input_module' not found";
92             }
93             }
94              
95 3         348 return $self->dumper->($info, $env);
96             }
97              
98             sub _allowed {
99 4     4   4 my ( $self , $address ) = @_;
100              
101 4 50       21 if ( $address =~ /:/) {
102 0 0       0 return unless $self->{__cidr6};
103 0         0 return $self->{__cidr6}->find( $address );
104             }
105 4 100       15 return unless $self->{__cidr4};
106 3         14 return $self->{__cidr4}->find( $address );
107             }
108              
109             1;
110              
111             __END__