File Coverage

blib/lib/Plack/Middleware/Pod.pm
Criterion Covered Total %
statement 40 41 97.5
branch 8 12 66.6
condition 5 10 50.0
subroutine 7 7 100.0
pod 1 1 100.0
total 61 71 85.9


line stmt bran cond sub pod time code
1             package Plack::Middleware::Pod;
2 2     2   57483 use strict;
  2         4  
  2         46  
3 2     2   1009 use Pod::POM;
  2         35234  
  2         93  
4 2     2   10 use parent qw( Plack::Middleware );
  2         6  
  2         6  
5 2     2   9352 use vars qw($VERSION);
  2         2  
  2         135  
6             $VERSION = '0.05';
7              
8 2         8 use Plack::Util::Accessor qw(
9             path
10             root
11             pass_through
12             pod_view
13 2     2   9 );
  2         2  
14              
15             =head1 NAME
16              
17             Plack::Middleware::Pod - render POD files as HTML
18              
19             =head1 SYNOPSIS
20              
21             enable "Plack::Middleware::Pod",
22             path => qr{^/pod/},
23             root => './',
24             pod_view => 'Pod::POM::View::HTML', # the default
25             ;
26              
27             =cut
28              
29             sub call {
30 2     2 1 94840 my $self = shift;
31 2         3 my $env = shift;
32            
33 2         8 my $res = $self->_handle_pod($env);
34 2 100 33     9171 if ($res && not ($self->pass_through and $res->[0] == 404)) {
      66        
35 1         21 return $res;
36             }
37              
38 1         10 return $self->app->($env);
39             }
40              
41             sub _handle_pod {
42 2     2   3 my($self, $env) = @_;
43            
44 2         8 my $path_match = $self->path;
45              
46 2 50       50 $path_match or return;
47 2         4 my $path = $env->{PATH_INFO};
48              
49             # We don't allow relative names, just to be sure
50 2         4 $path =~ s!^(\.\./)+!!g;
51 2         12 1 while $path =~ s!([^/]+/\.\./)!/!;
52            
53             # Sorry if you want to use whitespace in pod filenames
54 2 50       11 $path =~ m!^[-_./\w\d]+$!
55             or return;
56              
57             #warn "[$path]";
58             #warn "Checking against $path_match";
59              
60 2         9 for ($path) {
61 2 50       13 my $matched = 'CODE' eq ref $path_match ? $path_match->($_, $env) : $_ =~ $path_match;
62 2 100       6 return unless $matched;
63             }
64              
65 1   50     5 my $r = $self->root || './';
66             #warn "Stripping '$path_match' from $path, replacing by '$r'";
67 1         11 $path =~ s!$path_match!$r!;
68             #warn "Rendering [$path]";
69              
70 1 50       18 if( -f $path) {
71             # Render the Pod to HTML
72 1   50     3 my $v = $self->pod_view || 'Pod::POM::View::HTML';
73 1         7 my $pod_viewer = $v;
74             # Load the viewer class
75 1         3 $pod_viewer =~ s!::!/!g;
76 1         465 require "$pod_viewer.pm"; # will crash if not found
77            
78 1         4192 my $pom = Pod::POM->new->parse_file($path);
79            
80             return [
81 1         2804 200, ["Content-Type" => "text/html"], [$v->print($pom)]
82             ];
83             } else {
84             #warn "[$path] not found";
85             return
86 0           }
87             }
88              
89             1;
90              
91             =head1 SECURITY CONSIDERATIONS
92              
93             This middleware tries to be conservative regarding access to directories outside
94             of the C directory, but you are advised to not enable this middleware
95             in a webserver accessible to a wider public. This middleware might allow
96             leaking data from outside the directory.
97              
98             =head1 REPOSITORY
99              
100             The public repository of this module is
101             L.
102              
103             =head1 SUPPORT
104              
105             The public support forum of this module is
106             L.
107              
108             =head1 BUG TRACKER
109              
110             Please report bugs in this module via the RT CPAN bug queue at
111             L
112             or via mail to L.
113              
114             =head1 AUTHOR
115              
116             Max Maischein C
117              
118             =head1 COPYRIGHT (c)
119              
120             Copyright 2014-2016 by Max Maischein C.
121              
122             =head1 LICENSE
123              
124             This module is released under the same terms as Perl itself.
125              
126             =cut