File Coverage

blib/lib/Net/BitTorrent/Protocol/BEP09.pm
Criterion Covered Total %
statement 17 17 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 23 23 100.0


line stmt bran cond sub pod time code
1 22     22   193341 use v5.40;
  22         81  
2 22     22   133 use feature 'class', 'try';
  22         43  
  22         2990  
3 22     22   150 no warnings 'experimental::class', 'experimental::try';
  22         71  
  22         2550  
4 22     22   11324 class Net::BitTorrent::Protocol::BEP09 v2.0.0 : isa(Net::BitTorrent::Protocol::BEP10) {
  22         67  
  22         1293  
5 22     22   164 use Net::BitTorrent::Protocol::BEP03::Bencode qw[bencode bdecode];
  22         41  
  22         1584  
6              
7             # BEP 09 Message Types
8 22     22   132 use constant { METADATA_REQUEST => 0, METADATA_DATA => 1, METADATA_REJECT => 2, };
  22         41  
  22         24662  
9             ADJUST {
10             $self->on(
11             extended_message => sub ( $self, $name, $payload ) {
12             return unless $name eq 'ut_metadata';
13             my ( $dict, $remaining );
14             try {
15             my @res = bdecode( $payload, 1 );
16             if ( ref $res[0] eq 'HASH' ) {
17             ( $dict, $remaining ) = @res;
18             }
19             else { # Odd number of elements: KV pairs + leftover
20             $remaining = pop @res;
21             $dict = {@res};
22             }
23             }
24             catch ($e) {
25             $self->_emit( log => " [ERROR] Malformed ut_metadata message: $e\n", level => 'error' );
26             return;
27             }
28             if ( ref $dict ne 'HASH' ) {
29             $self->_emit( log => " [ERROR] Malformed ut_metadata message: dict is not a hash\n", level => 'error' );
30             return;
31             }
32             my $type = $dict->{msg_type};
33             if ( !defined $type ) {
34             $self->_emit( log => " [ERROR] ut_metadata message missing msg_type\n", level => 'error' );
35             return;
36             }
37             if ( $type == METADATA_REQUEST ) {
38             $self->_emit( metadata_request => $dict->{piece} );
39             }
40             elsif ( $type == METADATA_DATA ) {
41             $self->_emit(
42             log => " [DEBUG] Received metadata data for piece $dict->{piece} (len " . length($remaining) . ")\n",
43             level => 'debug'
44             ) if $self->debug;
45             $self->_emit( metadata_data => $dict->{piece}, $dict->{total_size}, $remaining );
46             }
47             elsif ( $type == METADATA_REJECT ) {
48             $self->_emit( metadata_reject => $dict->{piece} );
49             }
50             else {
51             $self->_emit( log => " [DEBUG] Unknown ut_metadata msg_type: $type\n", level => 'debug' ) if $self->debug;
52             }
53             }
54             );
55             }
56              
57             method send_metadata_request ($piece) {
58             return unless exists $self->remote_extensions->{ut_metadata};
59             $self->_emit( log => " [DEBUG] Sending metadata request for piece $piece\n", level => 'debug' ) if $self->debug;
60             my $payload = bencode( { msg_type => METADATA_REQUEST, piece => $piece, } );
61             $self->send_ext_message( 'ut_metadata', $payload );
62             }
63              
64             method send_metadata_data ( $piece, $total_size, $data ) {
65             return unless exists $self->remote_extensions->{ut_metadata};
66             my $header = bencode( { msg_type => METADATA_DATA, piece => $piece, total_size => $total_size, } );
67             $self->send_ext_message( 'ut_metadata', $header . $data );
68             }
69              
70             method send_metadata_reject ($piece) {
71             return unless exists $self->remote_extensions->{ut_metadata};
72             my $payload = bencode( { msg_type => METADATA_REJECT, piece => $piece, } );
73             $self->send_ext_message( 'ut_metadata', $payload );
74             }
75             } 1;