File Coverage

blib/lib/POE/Component/Client/Icecast.pm
Criterion Covered Total %
statement 24 55 43.6
branch 0 16 0.0
condition 2 20 10.0
subroutine 8 15 53.3
pod 1 1 100.0
total 35 107 32.7


line stmt bran cond sub pod time code
1             package POE::Component::Client::Icecast;
2 1     1   28286 use strict;
  1         2  
  1         35  
3 1     1   5 use warnings;
  1         2  
  1         30  
4              
5 1     1   5 use Carp 'carp', 'croak';
  1         6  
  1         64  
6 1     1   11873 use POE::Session;
  1         7476  
  1         6  
7 1     1   911 use POE::Filter::Stream;
  1         2282  
  1         27  
8 1     1   1511 use POE::Component::Client::TCP;
  1         571118  
  1         45  
9              
10 1   50 1   11 use constant TRACE => $ENV{'ICECAST_TRACE'} || 0;
  1         2  
  1         101  
11 1   50 1   7 use constant DEBUG => $ENV{'ICECAST_DEBUG'} || 0;
  1         2  
  1         822  
12              
13             our $VERSION = 0.6;
14              
15             sub new {
16 0     0 1   my $type = shift;
17 0           my $param = {@_};
18            
19 0           my $mi = $type.'->new()'; # hi, Rocco Caputto!
20 0 0         croak "$mi requires an even number of parameters" if @_ & 1;
21            
22 0 0         my $stream = $param->{'Stream'} ? _parse_stream_param($param->{'Stream'}) : {};
23 0   0       my $path = $stream->{'Path'} || $param->{'Path'} || croak "$mi requires Path param to stream";
24 0 0         $path = "/$path" unless $path =~ m{^/};
25            
26 0   0       POE::Component::Client::TCP->new(
27             (map { $_ => $stream->{$_} || $param->{$_} } 'Alias', 'RemoteAddress', 'RemotePort', 'BindAddress', 'BindPort'),
28            
29             'Filter' => POE::Filter::Stream->new,
30             'Connected' => sub {
31 0     0     $_[HEAP]->{'server'}->put(grep { DEBUG && warn $_;1 } join "\n",
  0            
  0            
32             "GET $path HTTP/1.0",
33             'Icy-MetaData: 1',
34             ('') x 2
35             );
36             },
37            
38             'ServerInput' => sub {
39 0     0     DEBUG && warn 'Server input ' . length $_[ARG0];
40 0 0         return unless my %tag = $_[ARG0] =~ /Stream(\w+)='(.*?)';/g;
41 0           DEBUG && warn $tag{'Title'};
42            
43             {
44 0           local $_[ARG0] = \%tag;
  0            
45 0 0         ref $param->{'GetTags'} eq 'CODE' && $param->{'GetTags'}->(@_);
46             }
47             },
48            
49             'Disconnected' => sub {
50 0     0     DEBUG && warn "$mi disconnected";
51            
52 0 0         if ($param->{'Reconnect'}) {
53 0           DEBUG && warn "$mi will reconnect, delay is $param->{'Reconnect'}";
54 0           $_[KERNEL]->delay('reconnect' => $param->{'Reconnect'});
55             }
56             },
57            
58             'ConnectError' => sub {
59 0     0     warn "$param->{'Stream'} connect error: " . $_[ARG2] . "\n";
60            
61 0 0         if ($param->{'Reconnect'}) {
62 0           DEBUG && warn "$mi will reconnect, delay is $param->{'Reconnect'}";
63 0           $_[KERNEL]->delay('reconnect' => $param->{'Reconnect'});
64             }
65             },
66             'ServerError' => sub {
67             # XXX: can croak if args
68 0     0     warn "$param->{'Stream'} server error: " . $_[ARG0] . "\n";
69             },
70            
71 0 0         'SessionParams' => [ 'options' => { 'trace' => TRACE } ],
72             ) or croak "$mi has error: $!";
73             }
74              
75             #
76              
77             sub _parse_stream_param {
78 0   0 0     my $stream = shift || return {};
79            
80 0           my($domain, $path) = $stream =~ m{^ http :// ([^/]+) / (.*) }x;
81 0           my($addr, $port) = $domain =~ m{^ (.*) : (.*) }x;
82             return {
83 0   0       'Host' => $addr || $domain,
      0        
      0        
84             'RemoteAddress' => $addr || $domain,
85             'RemotePort' => $port || 80,
86             'Path' => $path,
87             };
88             }
89              
90             1;
91              
92             __END__