File Coverage

blib/lib/AnyEvent/HTTPD/Util.pm
Criterion Covered Total %
statement 53 56 94.6
branch 5 6 83.3
condition n/a
subroutine 11 11 100.0
pod 0 6 0.0
total 69 79 87.3


line stmt bran cond sub pod time code
1             package AnyEvent::HTTPD::Util;
2 12     12   1663 use AnyEvent;
  12         6211  
  12         310  
3 12     12   16577 use AnyEvent::Socket;
  12         271415  
  12         2097  
4 12     12   160 use common::sense;
  12         27  
  12         129  
5              
6             require Exporter;
7             our @ISA = qw/Exporter/;
8              
9             our @EXPORT = qw/parse_urlencoded url_unescape header_set
10             header_get header_exists/;
11              
12             =head1 NAME
13              
14             AnyEvent::HTTPD::Util - Utility functions for AnyEvent::HTTPD
15              
16             =head1 SYNOPSIS
17              
18             =head1 DESCRIPTION
19              
20             The functions in this package are not public.
21              
22             =over 4
23              
24             =cut
25              
26             sub url_unescape {
27 8     8 0 16 my ($val) = @_;
28 8         14 $val =~ s/\+/\040/g;
29 8         27 $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr (hex ($1))/eg;
  8         31  
30 8         26 $val
31             }
32              
33             sub parse_urlencoded {
34 12     12 0 1544 my ($cont) = @_;
35 12         66 my (@pars) = split /[\&\;]/, $cont;
36 12         84 $cont = {};
37              
38 12         44 for (@pars) {
39 4         16 my ($name, $val) = split /=/, $_;
40 4         112 $name = url_unescape ($name);
41 4         11 $val = url_unescape ($val);
42              
43 4         7 push @{$cont->{$name}}, [$val, ''];
  4         282  
44             }
45             $cont
46 12         65 }
47              
48             sub test_connect {
49 8     8 0 25 my ($host, $port, $data) = @_;
50              
51 8         251 my $c = AE::cv;
52              
53 8         3877 my $t; $t = AnyEvent->timer (after => 0.1, cb => sub {
54 8     8   1720 my $hdl;
55             my $buf;
56 8         19 undef $t;
57             tcp_connect $host, $port, sub {
58 8 50       3865 my ($fh) = @_
59             or die "couldn't connect: $!";
60              
61             $hdl =
62             AnyEvent::Handle->new (
63             fh => $fh,
64             timeout => 15,
65             on_eof => sub {
66 8         1015 $c->send ($buf);
67 8         90 undef $hdl;
68             },
69             on_timeout => sub {
70 0         0 warn "test_connect timed out";
71 0         0 $c->send ($buf);
72 0         0 undef $hdl;
73             },
74             on_read => sub {
75 8         1495 $buf .= $hdl->rbuf;
76 8         93 $hdl->rbuf = '';
77 8         127 });
78 8         1722 $hdl->push_write ($data);
79 8         75 };
80 8         106 });
81              
82 8         210 $c
83             }
84              
85             ###
86             # these functions set/get/check existence of a header name:value pair while
87             # ignoring the case of the name
88             #
89             # quick hack, does not scale to large hashes. however, it's not expected to be
90             # run on large hashes.
91             #
92             # a more performant alternative would be to keep two hashes for each set of
93             # headers, one for the headers in the case they like, and one a mapping of
94             # names from some consistent form (say, all lowercase) to the name in the other
95             # hash, including capitalization. (this style is used in HTTP::Headers)
96              
97             sub _header_transform_case_insens {
98 270     270   383 my $lname = lc $_[1];
99 270         258 my (@names) = grep { $lname eq lc ($_) } keys %{$_[0]};
  856         1753  
  270         643  
100 270 100       853 @names ? $names[0] : $_[1]
101             }
102              
103             sub header_set {
104 121     121 0 217 my ($hdrs, $name, $value) = @_;
105 121         176 $name = _header_transform_case_insens ($hdrs, $name);
106 121         416 $hdrs->{$name} = $value;
107             }
108              
109             sub header_get {
110 49     49 0 82 my ($hdrs, $name) = @_;
111 49         83 $name = _header_transform_case_insens ($hdrs, $name);
112 49 100       269 exists $hdrs->{$name} ? $hdrs->{$name} : undef
113             }
114              
115             sub header_exists {
116 100     100 0 144 my ($hdrs, $name) = @_;
117 100         182 $name = _header_transform_case_insens ($hdrs, $name);
118             # NB: even if the value is undefined, return true
119 100         805 return exists $hdrs->{$name}
120             }
121              
122             =back
123              
124             =head1 AUTHOR
125              
126             Robin Redeker, C<< <elmex@ta-sa.org> >>
127              
128             =head1 SEE ALSO
129              
130             =head1 COPYRIGHT & LICENSE
131              
132             Copyright 2009-2011 Robin Redeker, all rights reserved.
133              
134             This program is free software; you can redistribute it and/or modify it
135             under the same terms as Perl itself.
136              
137             =cut
138              
139             1;
140