File Coverage

blib/lib/POE/Component/Server/HTTPServer/StaticHandler.pm
Criterion Covered Total %
statement 15 76 19.7
branch 0 24 0.0
condition n/a
subroutine 5 9 55.5
pod 3 3 100.0
total 23 112 20.5


line stmt bran cond sub pod time code
1             package POE::Component::Server::HTTPServer::StaticHandler;
2 1     1   1054 use strict;
  1         1  
  1         31  
3 1     1   1226 use HTTP::Status;
  1         2  
  1         315  
4 1     1   746 use MIME::Types;
  1         4708  
  1         34  
5 1     1   8 use POE::Component::Server::HTTPServer::Handler;
  1         2  
  1         43  
6 1     1   4 use base 'POE::Component::Server::HTTPServer::Handler';
  1         1  
  1         644  
7              
8             # _init( $root [, index_file => $index_file] [, auto_index => $auto_index ] )
9             # Files will be served relative to $root
10             # If a request is made for a directory, then:
11             # If $index_file is defined and found, it will be returned.
12             # Else, if $auto_index is defined, a directory index will be generated.
13             # Otherwise, this handler will pass on the request.
14             sub _init {
15 0     0     my $self = shift;
16 0           my $root = shift;
17 0           my %args = @_;
18 0           $self->{root} = $root;
19 0           $self->{mimetypes} = MIME::Types->new(); # ugh
20 0 0         if ( exists($args{index_file}) ) {
21 0           $self->{index_file} = $args{index_file};
22             } else {
23 0           $self->{index_file} = 'index.html';
24             }
25 0 0         if ( exists($args{auto_index}) ) {
26 0           $self->{auto_index} = $args{auto_index};
27             } else {
28 0           $self->{auto_index} = 0;
29             }
30             }
31              
32             sub handle {
33 0     0 1   my $self = shift;
34 0           my $context = shift;
35             #print "Handling static request (", __PACKAGE__, ")\n";
36 0           my $cpath = $context->{contextpath};
37             #print "Context path=$cpath\n";
38             # scrub path (badly): XXX fix this with file::spec or the like
39 0 0         if ( $cpath =~ m[(^|/)\.\.(/|$)] ) {
40 0           warn "Will not serve dangerous path '$cpath'\n"; # should keep silent here
41 0           return H_CONT;
42             }
43 0           my $filepath = "$self->{root}/$cpath";
44             #print "static root: $filepath\n";
45 0 0         if ( -d $filepath ) {
    0          
46 0           return $self->handle_directory($filepath, $context);
47             } elsif ( -f $filepath ) {
48 0           return $self->handle_plainfile($filepath, $context);
49             } else {
50             #print "Request for non-existant file: $filepath\n";
51 0           return H_CONT;
52             }
53             }
54              
55             sub handle_plainfile {
56 0     0 1   my $self = shift;
57 0           my $filepath = shift;
58 0           my $context = shift;
59 0 0         if ( open(my $in, $filepath) ) {
60 0           binmode($in);
61 0           local $/ = undef;
62 0           $context->{response}->code( RC_OK );
63 0           my $type = $self->{mimetypes}->mimeTypeOf( $filepath );
64 0 0         $type='text/plain' unless defined($type);
65 0           $context->{response}->content_type( $type );
66 0           $context->{response}->content(<$in>);
67 0           return H_FINAL;
68             } else {
69             #print "Failed to open $filepath ($!)\n";
70 0           $context->{error_message} = $!; # XXX security: returned with 404 response
71 0           return H_CONT;
72             }
73             }
74              
75             sub handle_directory {
76 0     0 1   my $self = shift;
77 0           my $filepath = shift;
78 0           my $context = shift;
79             #print "directory( $filepath )\n";
80 0 0         if ( $self->{index_file} ) {
81 0           my $index_file = "$filepath/$self->{index_file}";
82 0 0         if ( -e $index_file ) {
83 0           return $self->handle_plainfile( $index_file, $context );
84             }
85             }
86 0 0         if ( $self->{auto_index} ) {
87             # nasty hack: should probably just not include this option
88 0 0         if ( opendir(my $dir, $filepath) ) {
89 0           my $page = qq{Directory Index\n};
90 0           $page .= qq{\n};
91 0           $page .= qq{

Directory Index


\n};
92 0           $page .= qq{
    \n};
93 0           my $base = $context->{request}->uri;
94 0           while(my $fn = readdir($dir)) {
95 0 0         next if $fn=~/^\./;
96 0           $page .= qq{
  • $fn
  • \n};
    97             }
    98 0           $page .= qq{\n};
    99 0           $page .= qq{\n};
    100 0           $context->{response}->code( RC_OK );
    101 0           $context->{response}->content( $page );
    102 0           return H_FINAL;
    103             } else {
    104             # XXX should this class of problem be a 500?
    105             #print "Failed to opendir ($!)\n";
    106 0           $context->{error_message} = $!; # XXX security: returned with 404 resp
    107 0           return H_CONT;
    108             }
    109             }
    110 0           return H_CONT;
    111             }
    112              
    113             1;
    114             __END__