File Coverage

lib/PMLTQ/Suggest/Server.pm
Criterion Covered Total %
statement 15 72 20.8
branch 0 24 0.0
condition 0 8 0.0
subroutine 5 12 41.6
pod 3 7 42.8
total 23 123 18.7


line stmt bran cond sub pod time code
1             package PMLTQ::Suggest::Server;
2             our $AUTHORITY = 'cpan:MATY';
3             $PMLTQ::Suggest::Server::VERSION = '1.0.4';
4 1     1   549446 use base qw(HTTP::Server::Simple::CGI);
  1         11  
  1         512  
5 1     1   8084 use URI;
  1         3  
  1         19  
6 1     1   5 use URI::file;
  1         3  
  1         19  
7              
8 1     1   461 use PMLTQ::Suggest::Utils;
  1         3  
  1         11  
9 1     1   471 use PMLTQ::Suggest;
  1         3  
  1         11  
10              
11             our $permitted_paths_re = '^(?:)/';
12             our %methods = map {$_ => 1} qw/GET/;
13              
14             sub run {
15 0     0 1   my $self = shift;
16 0 0         if ($self->prefork) {
17 0           $self->SUPER::run(@_, host => $self->host, ipv => 4, max_servers => $self->prefork);
18             } else {
19 0           $self->SUPER::run(@_);
20             }
21             }
22              
23             sub handle_request {
24 0     0 1   my ($self, $cgi) = @_;
25 0           eval {
26 0           my $path = $cgi->path_info();
27 0           my $method = $cgi->request_method();
28 0 0 0       if ($path eq '/' and exists($methods{$method})) {
29 0           servePMLTQ($self,$cgi);
30             } else {
31 0           notFound($cgi);
32             }
33             };
34              
35 0 0         serverError($cgi, $@) if ($@);
36             }
37              
38             # Maximum number of servers to prefork
39             sub prefork {
40 0     0 0   my $self = shift;
41 0 0         $self->{prefork_child} = $_[0] if scalar @_ > 0;
42 0           return $self->{prefork_child};
43             }
44              
45 0 0   0 1   sub net_server { return $_[0]->prefork ? 'Net::Server::PreForkSimple' : undef; }
46              
47             sub notFound {
48 0     0 0   my ($cgi)=@_;
49 0           print "HTTP/1.0 404 Not found\r\n";
50 0           print $cgi->header,
51             $cgi->start_html('Not found'),
52             $cgi->h1('Not found'),
53             $cgi->end_html;
54             }
55              
56             sub serverError {
57 0     0 0   my ($cgi, $error)=(@_,'');
58 0           $error =~ tr/\n/ /;
59 0           $error =~ s/ at .*$//;
60 0           $error =~ s/\.\.\.propagated.*$//;
61 0           print STDERR '['.localtime()."] $error\n";
62 0           $error =~ s/'\/[^']*\/([^\/']*)'/'$1'/;
63              
64 0           print "HTTP/1.0 500 Internal server error\r\n";
65 0           print $cgi->header,
66             $cgi->start_html('Internal server error'),
67             $cgi->h1('Error occurred while processing request!'),
68             "\r\n",
69             $cgi->p($error),
70             $cgi->end_html;
71             }
72              
73             sub servePMLTQ {
74 0     0 0   my ($self,$cgi) = @_; # Net::HTTPServer::Request object
75 0   0       my @names = split(/,/,$cgi->param('r')||'');
76 0           my $paths = $cgi->param('p');
77 0 0         my @paths = $paths ? split(/\|/, $paths) : ();
78 0 0         unless (@paths) {
79 0           print STDERR '['.localtime()."] No path!\n";
80 0           return notFound($cgi);
81             }
82 0           my @positions;
83 0           foreach my $p (@paths) {
84 0           my ($path, $goto)=PMLTQ::Suggest::Utils::parse_file_suffix($p);
85 0           $path = URI->new($path)->canonical->as_string;
86 0 0 0       if ($path=~m{/\.\./} or $path !~ $permitted_paths_re) {
    0          
87 0           print STDERR '['.localtime()."] Path $path not permitted\n";
88 0           return notFound($cgi);
89             } elsif (!$goto) {
90 0           print STDERR '['.localtime()."] Path $p does not contain an address\n";
91 0           return notFound($cgi);
92             }
93 0           push @positions, [$path,$goto];
94             }
95 0           my $pmltq;
96 0           eval {
97             $pmltq = PMLTQ::Suggest::make_pmltq(
98             \@positions,
99 0 0         (@names ? (reserved_names => {map {$_=>1} @names}) : ()),
  0            
100             verbose => 1
101             );
102             };
103 0 0         if (!defined $pmltq) {
104 0 0         $@ = "Empty query! Possible error - unable to find node in file" unless $@;
105 0           die; # send error upper
106             } else {
107 0           print STDERR '['.localtime()."] Serving PMLTQ for $paths: $pmltq\n";
108 0           binmode(select());
109 0           Encode::_utf8_off($pmltq);
110 0           print "HTTP/1.0 200 OK\r\n";
111 0           print $cgi->header(-type => 'text/plain',
112             -charset => 'UTF-8',
113             # -Content_length => ((stat($fh))[7]),
114             );
115 0           print $pmltq;
116             }
117             }
118              
119             1;