line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Perlbal::ChunkedUploadState; |
2
|
22
|
|
|
22
|
|
135
|
use strict; |
|
22
|
|
|
|
|
56
|
|
|
22
|
|
|
|
|
13340
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
sub new { |
5
|
3
|
|
|
3
|
0
|
13
|
my ($pkg, %args) = @_; |
6
|
3
|
|
|
|
|
20
|
my $self = bless { |
7
|
|
|
|
|
|
|
'buf' => '', |
8
|
|
|
|
|
|
|
'bytes_remain' => 0, # remaining in chunk (ignoring final 2 byte CRLF) |
9
|
|
|
|
|
|
|
}, $pkg; |
10
|
3
|
|
|
|
|
9
|
foreach my $k (qw(on_new_chunk on_disconnect on_zero_chunk)) { |
11
|
9
|
|
50
|
0
|
|
47
|
$self->{$k} = (delete $args{$k}) || sub {}; |
|
0
|
|
|
|
|
0
|
|
12
|
|
|
|
|
|
|
} |
13
|
3
|
50
|
|
|
|
13
|
die "bogus args" if %args; |
14
|
3
|
|
|
|
|
12
|
return $self; |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub on_readable { |
18
|
38
|
|
|
38
|
0
|
72
|
my ($self, $ds) = @_; |
19
|
38
|
|
|
|
|
207
|
my $rbuf = $ds->read(131072); |
20
|
38
|
50
|
|
|
|
2484
|
unless (defined $rbuf) { |
21
|
0
|
|
|
|
|
0
|
$self->{on_disconnect}->(); |
22
|
0
|
|
|
|
|
0
|
return; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
|
25
|
38
|
|
|
|
|
1730
|
$self->{buf} .= $$rbuf; |
26
|
|
|
|
|
|
|
|
27
|
38
|
|
|
|
|
134
|
while ($self->drive_machine) {} |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# returns 1 if progress was made parsing buffer |
31
|
|
|
|
|
|
|
sub drive_machine { |
32
|
98
|
|
|
98
|
0
|
135
|
my $self = shift; |
33
|
|
|
|
|
|
|
|
34
|
98
|
|
|
|
|
416
|
my $buflen = length($self->{buf}); |
35
|
98
|
100
|
|
|
|
432
|
return 0 unless $buflen; |
36
|
|
|
|
|
|
|
|
37
|
70
|
100
|
|
|
|
162
|
if (my $br = $self->{bytes_remain}) { |
38
|
44
|
100
|
|
|
|
96
|
my $extract = $buflen > $br ? $br : $buflen; |
39
|
44
|
|
|
|
|
3876
|
my $ch = substr($self->{buf}, 0, $extract, ''); |
40
|
44
|
|
|
|
|
81
|
$self->{bytes_remain} -= $extract; |
41
|
44
|
50
|
|
|
|
112
|
die "assert" if $self->{bytes_remain} < 0; |
42
|
44
|
|
|
|
|
183
|
$self->{on_new_chunk}->(\$ch); |
43
|
44
|
|
|
|
|
482
|
return 1; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
26
|
100
|
|
|
|
1463
|
return 0 unless $self->{buf} =~ s/^(?:\r\n)?([0-9a-fA-F]+)(?:;.*)?\r\n//; |
47
|
19
|
|
|
|
|
82
|
$self->{bytes_remain} = hex($1); |
48
|
|
|
|
|
|
|
|
49
|
19
|
100
|
|
|
|
53
|
if ($self->{bytes_remain} == 0) { |
50
|
|
|
|
|
|
|
# FIXME: new state machine state for trailer parsing/discarding. |
51
|
|
|
|
|
|
|
# (before we do on_zero_chunk). for now, though, just assume |
52
|
|
|
|
|
|
|
# no trailers and throw away the extra post-trailer \r\n that |
53
|
|
|
|
|
|
|
# is probably in this packet. hacky. |
54
|
3
|
|
|
|
|
18
|
$self->{buf} =~ s/^\r\n//; |
55
|
3
|
|
|
|
|
9
|
$self->{hit_zero} = 1; |
56
|
3
|
|
|
|
|
15
|
$self->{on_zero_chunk}->(); |
57
|
3
|
|
|
|
|
186
|
return 0; |
58
|
|
|
|
|
|
|
} |
59
|
16
|
|
|
|
|
69
|
return 1; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
12
|
|
|
12
|
0
|
65
|
sub hit_zero_chunk { $_[0]{hit_zero} } |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
1; |