| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Net::HTTP::Methods; |
|
2
|
|
|
|
|
|
|
our $VERSION = '6.23'; |
|
3
|
5
|
|
|
5
|
|
69812
|
use strict; |
|
|
5
|
|
|
|
|
23
|
|
|
|
5
|
|
|
|
|
158
|
|
|
4
|
5
|
|
|
5
|
|
25
|
use warnings; |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
123
|
|
|
5
|
5
|
|
|
5
|
|
2983
|
use URI; |
|
|
5
|
|
|
|
|
30004
|
|
|
|
5
|
|
|
|
|
3406
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
my $CRLF = "\015\012"; # "\r\n" is not portable |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
*_bytes = defined(&utf8::downgrade) ? |
|
10
|
|
|
|
|
|
|
sub { |
|
11
|
20
|
50
|
|
20
|
|
104
|
unless (utf8::downgrade($_[0], 1)) { |
|
12
|
0
|
|
|
|
|
0
|
require Carp; |
|
13
|
0
|
|
|
|
|
0
|
Carp::croak("Wide character in HTTP request (bytes required)"); |
|
14
|
|
|
|
|
|
|
} |
|
15
|
20
|
|
|
|
|
134
|
return $_[0]; |
|
16
|
|
|
|
|
|
|
} |
|
17
|
|
|
|
|
|
|
: |
|
18
|
|
|
|
|
|
|
sub { |
|
19
|
|
|
|
|
|
|
return $_[0]; |
|
20
|
|
|
|
|
|
|
}; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub new { |
|
24
|
5
|
|
|
5
|
0
|
4019
|
my $class = shift; |
|
25
|
5
|
100
|
|
|
|
21
|
unshift(@_, "Host") if @_ == 1; |
|
26
|
5
|
|
|
|
|
20
|
my %cnf = @_; |
|
27
|
5
|
|
|
|
|
436
|
require Symbol; |
|
28
|
5
|
|
|
|
|
771
|
my $self = bless Symbol::gensym(), $class; |
|
29
|
5
|
|
|
|
|
89
|
return $self->http_configure(\%cnf); |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub http_configure { |
|
33
|
8
|
|
|
8
|
0
|
31
|
my($self, $cnf) = @_; |
|
34
|
|
|
|
|
|
|
|
|
35
|
8
|
50
|
|
|
|
30
|
die "Listen option not allowed" if $cnf->{Listen}; |
|
36
|
8
|
|
|
|
|
21
|
my $explicit_host = (exists $cnf->{Host}); |
|
37
|
8
|
|
|
|
|
17
|
my $host = delete $cnf->{Host}; |
|
38
|
|
|
|
|
|
|
# All this because $cnf->{PeerAddr} = 0 is actually valid. |
|
39
|
8
|
|
|
|
|
16
|
my $peer; |
|
40
|
8
|
|
|
|
|
21
|
for my $key (qw{PeerAddr PeerHost}) { |
|
41
|
14
|
100
|
66
|
|
|
61
|
next if !defined($cnf->{$key}) || q{} eq $cnf->{$key}; |
|
42
|
2
|
|
|
|
|
6
|
$peer = $cnf->{$key}; |
|
43
|
2
|
|
|
|
|
5
|
last; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
8
|
100
|
|
|
|
39
|
if (!defined $peer) { |
|
46
|
6
|
50
|
|
|
|
19
|
die "No Host option provided" unless $host; |
|
47
|
6
|
|
|
|
|
17
|
$cnf->{PeerAddr} = $peer = $host; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# CONNECTIONS |
|
51
|
|
|
|
|
|
|
# PREFER: port number from PeerAddr, then PeerPort, then http_default_port |
|
52
|
8
|
|
|
|
|
53
|
my $peer_uri = URI->new("http://$peer"); |
|
53
|
8
|
|
66
|
|
|
32497
|
$cnf->{"PeerPort"} = $peer_uri->_port || $cnf->{PeerPort} || $self->http_default_port; |
|
54
|
8
|
|
|
|
|
178
|
$cnf->{"PeerAddr"} = $peer_uri->host; |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# HOST header: |
|
57
|
|
|
|
|
|
|
# If specified but blank, ignore. |
|
58
|
|
|
|
|
|
|
# If specified with a value, add the port number |
|
59
|
|
|
|
|
|
|
# If not specified, set to PeerAddr and port number |
|
60
|
|
|
|
|
|
|
# ALWAYS: If IPv6 address, use [brackets] (thanks to the URI package) |
|
61
|
|
|
|
|
|
|
# ALWAYS: omit port number if http_default_port |
|
62
|
8
|
100
|
100
|
|
|
276
|
if (($host) || (! $explicit_host)) { |
|
63
|
7
|
100
|
|
|
|
56
|
my $uri = ($explicit_host) ? URI->new("http://$host") : $peer_uri->clone; |
|
64
|
7
|
100
|
|
|
|
447
|
if (!$uri->_port) { |
|
65
|
|
|
|
|
|
|
# Always use *our* $self->http_default_port instead of URI's (Covers HTTP, HTTPS) |
|
66
|
6
|
|
33
|
|
|
177
|
$uri->port( $cnf->{PeerPort} || $self->http_default_port); |
|
67
|
|
|
|
|
|
|
} |
|
68
|
7
|
|
|
|
|
484
|
my $host_port = $uri->host_port; # Returns host:port or [ipv6]:port |
|
69
|
7
|
|
|
|
|
184
|
my $remove = ":" . $self->http_default_port; # we want to remove the default port number |
|
70
|
7
|
100
|
|
|
|
40
|
if (substr($host_port,0-length($remove)) eq $remove) { |
|
71
|
5
|
|
|
|
|
16
|
substr($host_port,0-length($remove)) = ""; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
7
|
|
|
|
|
38
|
$host = $host_port; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
8
|
|
|
|
|
23
|
$cnf->{Proto} = 'tcp'; |
|
77
|
|
|
|
|
|
|
|
|
78
|
8
|
|
|
|
|
17
|
my $keep_alive = delete $cnf->{KeepAlive}; |
|
79
|
8
|
|
|
|
|
15
|
my $http_version = delete $cnf->{HTTPVersion}; |
|
80
|
8
|
50
|
|
|
|
25
|
$http_version = "1.1" unless defined $http_version; |
|
81
|
8
|
|
|
|
|
20
|
my $peer_http_version = delete $cnf->{PeerHTTPVersion}; |
|
82
|
8
|
100
|
|
|
|
23
|
$peer_http_version = "1.0" unless defined $peer_http_version; |
|
83
|
8
|
|
|
|
|
14
|
my $send_te = delete $cnf->{SendTE}; |
|
84
|
8
|
|
|
|
|
15
|
my $max_line_length = delete $cnf->{MaxLineLength}; |
|
85
|
8
|
100
|
|
|
|
20
|
$max_line_length = 8*1024 unless defined $max_line_length; |
|
86
|
8
|
|
|
|
|
13
|
my $max_header_lines = delete $cnf->{MaxHeaderLines}; |
|
87
|
8
|
50
|
|
|
|
22
|
$max_header_lines = 128 unless defined $max_header_lines; |
|
88
|
|
|
|
|
|
|
|
|
89
|
8
|
100
|
|
|
|
30
|
return undef unless $self->http_connect($cnf); |
|
90
|
|
|
|
|
|
|
|
|
91
|
7
|
|
|
|
|
361109
|
$self->host($host); |
|
92
|
7
|
|
|
|
|
37
|
$self->keep_alive($keep_alive); |
|
93
|
7
|
|
|
|
|
44
|
$self->send_te($send_te); |
|
94
|
7
|
|
|
|
|
42
|
$self->http_version($http_version); |
|
95
|
7
|
|
|
|
|
48
|
$self->peer_http_version($peer_http_version); |
|
96
|
7
|
|
|
|
|
48
|
$self->max_line_length($max_line_length); |
|
97
|
7
|
|
|
|
|
37
|
$self->max_header_lines($max_header_lines); |
|
98
|
|
|
|
|
|
|
|
|
99
|
7
|
|
|
|
|
16
|
${*$self}{'http_buf'} = ""; |
|
|
7
|
|
|
|
|
23
|
|
|
100
|
|
|
|
|
|
|
|
|
101
|
7
|
|
|
|
|
63
|
return $self; |
|
102
|
|
|
|
|
|
|
} |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub http_default_port { |
|
105
|
11
|
|
|
11
|
0
|
359
|
80; |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# set up property accessors |
|
109
|
|
|
|
|
|
|
for my $method (qw(host keep_alive send_te max_line_length max_header_lines peer_http_version)) { |
|
110
|
|
|
|
|
|
|
my $prop_name = "http_" . $method; |
|
111
|
5
|
|
|
5
|
|
41
|
no strict 'refs'; |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
16850
|
|
|
112
|
|
|
|
|
|
|
*$method = sub { |
|
113
|
85
|
|
|
85
|
|
2855
|
my $self = shift; |
|
114
|
85
|
|
|
|
|
110
|
my $old = ${*$self}{$prop_name}; |
|
|
85
|
|
|
|
|
194
|
|
|
115
|
85
|
100
|
|
|
|
191
|
${*$self}{$prop_name} = shift if @_; |
|
|
43
|
|
|
|
|
107
|
|
|
116
|
85
|
|
|
|
|
201
|
return $old; |
|
117
|
|
|
|
|
|
|
}; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# we want this one to be a bit smarter |
|
121
|
|
|
|
|
|
|
sub http_version { |
|
122
|
8
|
|
|
8
|
0
|
23
|
my $self = shift; |
|
123
|
8
|
|
|
|
|
13
|
my $old = ${*$self}{'http_version'}; |
|
|
8
|
|
|
|
|
21
|
|
|
124
|
8
|
50
|
|
|
|
27
|
if (@_) { |
|
125
|
8
|
|
|
|
|
23
|
my $v = shift; |
|
126
|
8
|
50
|
|
|
|
23
|
$v = "1.0" if $v eq "1"; # float |
|
127
|
8
|
50
|
66
|
|
|
82
|
unless ($v eq "1.0" or $v eq "1.1") { |
|
128
|
0
|
|
|
|
|
0
|
require Carp; |
|
129
|
0
|
|
|
|
|
0
|
Carp::croak("Unsupported HTTP version '$v'"); |
|
130
|
|
|
|
|
|
|
} |
|
131
|
8
|
|
|
|
|
16
|
${*$self}{'http_version'} = $v; |
|
|
8
|
|
|
|
|
25
|
|
|
132
|
|
|
|
|
|
|
} |
|
133
|
8
|
|
|
|
|
19
|
$old; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub format_request { |
|
137
|
20
|
|
|
20
|
0
|
35
|
my $self = shift; |
|
138
|
20
|
|
|
|
|
38
|
my $method = shift; |
|
139
|
20
|
|
|
|
|
34
|
my $uri = shift; |
|
140
|
|
|
|
|
|
|
|
|
141
|
20
|
50
|
|
|
|
76
|
my $content = (@_ % 2) ? pop : ""; |
|
142
|
|
|
|
|
|
|
|
|
143
|
20
|
|
|
|
|
49
|
for ($method, $uri) { |
|
144
|
40
|
|
|
|
|
179
|
require Carp; |
|
145
|
40
|
50
|
33
|
|
|
220
|
Carp::croak("Bad method or uri") if /\s/ || !length; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
20
|
|
|
|
|
52
|
push(@{${*$self}{'http_request_method'}}, $method); |
|
|
20
|
|
|
|
|
28
|
|
|
|
20
|
|
|
|
|
92
|
|
|
149
|
20
|
|
|
|
|
50
|
my $ver = ${*$self}{'http_version'}; |
|
|
20
|
|
|
|
|
72
|
|
|
150
|
20
|
|
50
|
|
|
35
|
my $peer_ver = ${*$self}{'http_peer_http_version'} || "1.0"; |
|
151
|
|
|
|
|
|
|
|
|
152
|
20
|
|
|
|
|
38
|
my @h; |
|
153
|
|
|
|
|
|
|
my @connection; |
|
154
|
20
|
|
|
|
|
71
|
my %given = (host => 0, "content-length" => 0, "te" => 0); |
|
155
|
20
|
|
|
|
|
62
|
while (@_) { |
|
156
|
12
|
|
|
|
|
37
|
my($k, $v) = splice(@_, 0, 2); |
|
157
|
12
|
|
|
|
|
27
|
my $lc_k = lc($k); |
|
158
|
12
|
50
|
|
|
|
34
|
if ($lc_k eq "connection") { |
|
159
|
0
|
|
|
|
|
0
|
$v =~ s/^\s+//; |
|
160
|
0
|
|
|
|
|
0
|
$v =~ s/\s+$//; |
|
161
|
0
|
|
|
|
|
0
|
push(@connection, split(/\s*,\s*/, $v)); |
|
162
|
0
|
|
|
|
|
0
|
next; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
12
|
50
|
|
|
|
31
|
if (exists $given{$lc_k}) { |
|
165
|
0
|
|
|
|
|
0
|
$given{$lc_k}++; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
12
|
|
|
|
|
45
|
push(@h, "$k: $v"); |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
20
|
50
|
33
|
|
|
68
|
if (length($content) && !$given{'content-length'}) { |
|
171
|
0
|
|
|
|
|
0
|
push(@h, "Content-Length: " . length($content)); |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
|
|
174
|
20
|
|
|
|
|
39
|
my @h2; |
|
175
|
20
|
50
|
33
|
|
|
73
|
if ($given{te}) { |
|
|
|
50
|
|
|
|
|
|
|
176
|
0
|
0
|
|
|
|
0
|
push(@connection, "TE") unless grep lc($_) eq "te", @connection; |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
elsif ($self->send_te && gunzip_ok()) { |
|
179
|
|
|
|
|
|
|
# gzip is less wanted since the IO::Uncompress::Gunzip interface for |
|
180
|
|
|
|
|
|
|
# it does not really allow chunked decoding to take place easily. |
|
181
|
0
|
|
|
|
|
0
|
push(@h2, "TE: deflate,gzip;q=0.3"); |
|
182
|
0
|
|
|
|
|
0
|
push(@connection, "TE"); |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
|
|
185
|
20
|
50
|
|
|
|
59
|
unless (grep lc($_) eq "close", @connection) { |
|
186
|
20
|
100
|
|
|
|
46
|
if ($self->keep_alive) { |
|
187
|
12
|
100
|
|
|
|
46
|
if ($peer_ver eq "1.0") { |
|
188
|
|
|
|
|
|
|
# from looking at Netscape's headers |
|
189
|
4
|
|
|
|
|
9
|
push(@h2, "Keep-Alive: 300"); |
|
190
|
4
|
|
|
|
|
9
|
unshift(@connection, "Keep-Alive"); |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
else { |
|
194
|
8
|
100
|
|
|
|
24
|
push(@connection, "close") if $ver ge "1.1"; |
|
195
|
|
|
|
|
|
|
} |
|
196
|
|
|
|
|
|
|
} |
|
197
|
20
|
100
|
|
|
|
70
|
push(@h2, "Connection: " . join(", ", @connection)) if @connection; |
|
198
|
20
|
50
|
|
|
|
64
|
unless ($given{host}) { |
|
199
|
20
|
|
|
|
|
28
|
my $h = ${*$self}{'http_host'}; |
|
|
20
|
|
|
|
|
48
|
|
|
200
|
20
|
100
|
|
|
|
74
|
push(@h2, "Host: $h") if $h; |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
20
|
|
|
|
|
108
|
return _bytes(join($CRLF, "$method $uri HTTP/$ver", @h2, @h, "", $content)); |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
sub write_request { |
|
208
|
20
|
|
|
20
|
0
|
18413
|
my $self = shift; |
|
209
|
20
|
|
|
|
|
77
|
$self->print($self->format_request(@_)); |
|
210
|
|
|
|
|
|
|
} |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub format_chunk { |
|
213
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
|
214
|
0
|
0
|
0
|
|
|
0
|
return $_[0] unless defined($_[0]) && length($_[0]); |
|
215
|
0
|
|
|
|
|
0
|
return _bytes(sprintf("%x", length($_[0])) . $CRLF . $_[0] . $CRLF); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub write_chunk { |
|
219
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
|
220
|
0
|
0
|
0
|
|
|
0
|
return 1 unless defined($_[0]) && length($_[0]); |
|
221
|
0
|
|
|
|
|
0
|
$self->print(_bytes(sprintf("%x", length($_[0])) . $CRLF . $_[0] . $CRLF)); |
|
222
|
|
|
|
|
|
|
} |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub format_chunk_eof { |
|
225
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
|
226
|
0
|
|
|
|
|
0
|
my @h; |
|
227
|
0
|
|
|
|
|
0
|
while (@_) { |
|
228
|
0
|
|
|
|
|
0
|
push(@h, sprintf "%s: %s$CRLF", splice(@_, 0, 2)); |
|
229
|
|
|
|
|
|
|
} |
|
230
|
0
|
|
|
|
|
0
|
return _bytes(join("", "0$CRLF", @h, $CRLF)); |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub write_chunk_eof { |
|
234
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
|
235
|
0
|
|
|
|
|
0
|
$self->print($self->format_chunk_eof(@_)); |
|
236
|
|
|
|
|
|
|
} |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub my_read { |
|
240
|
1290
|
50
|
|
1290
|
0
|
2237
|
die if @_ > 3; |
|
241
|
1290
|
|
|
|
|
1592
|
my $self = shift; |
|
242
|
1290
|
|
|
|
|
1698
|
my $len = $_[1]; |
|
243
|
1290
|
|
|
|
|
1904
|
for (${*$self}{'http_buf'}) { |
|
|
1290
|
|
|
|
|
3136
|
|
|
244
|
1290
|
100
|
|
|
|
2070
|
if (length) { |
|
245
|
86
|
|
|
|
|
154
|
$_[0] = substr($_, 0, $len, ""); |
|
246
|
86
|
|
|
|
|
169
|
return length($_[0]); |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
else { |
|
249
|
1204
|
50
|
|
|
|
1939
|
die "read timeout" unless $self->can_read; |
|
250
|
1204
|
|
|
|
|
10444
|
return $self->sysread($_[0], $len); |
|
251
|
|
|
|
|
|
|
} |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
sub my_readline { |
|
257
|
143
|
|
|
143
|
0
|
215
|
my $self = shift; |
|
258
|
143
|
|
|
|
|
199
|
my $what = shift; |
|
259
|
143
|
|
|
|
|
194
|
for (${*$self}{'http_buf'}) { |
|
|
143
|
|
|
|
|
390
|
|
|
260
|
143
|
|
|
|
|
212
|
my $max_line_length = ${*$self}{'http_max_line_length'}; |
|
|
143
|
|
|
|
|
259
|
|
|
261
|
143
|
|
|
|
|
220
|
my $pos; |
|
262
|
143
|
|
|
|
|
196
|
while (1) { |
|
263
|
|
|
|
|
|
|
# find line ending |
|
264
|
624
|
|
|
|
|
903
|
$pos = index($_, "\012"); |
|
265
|
624
|
100
|
|
|
|
1118
|
last if $pos >= 0; |
|
266
|
481
|
50
|
33
|
|
|
1359
|
die "$what line too long (limit is $max_line_length)" |
|
267
|
|
|
|
|
|
|
if $max_line_length && length($_) > $max_line_length; |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# need to read more data to find a line ending |
|
270
|
481
|
|
|
|
|
609
|
my $new_bytes = 0; |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
READ: |
|
273
|
|
|
|
|
|
|
{ # wait until bytes start arriving |
|
274
|
481
|
50
|
|
|
|
547
|
$self->can_read |
|
|
481
|
|
|
|
|
764
|
|
|
275
|
|
|
|
|
|
|
or die "read timeout"; |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# consume all incoming bytes |
|
278
|
481
|
|
|
|
|
1018
|
my $bytes_read = $self->sysread($_, 1024, length); |
|
279
|
481
|
50
|
0
|
|
|
6617
|
if(defined $bytes_read) { |
|
|
|
0
|
0
|
|
|
|
|
|
280
|
481
|
|
|
|
|
595
|
$new_bytes += $bytes_read; |
|
281
|
|
|
|
|
|
|
} |
|
282
|
1
|
|
|
1
|
|
485
|
elsif($!{EINTR} || $!{EAGAIN} || $!{EWOULDBLOCK}) { |
|
|
1
|
|
|
|
|
1341
|
|
|
|
1
|
|
|
|
|
10
|
|
|
283
|
0
|
|
|
|
|
0
|
redo READ; |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
else { |
|
286
|
|
|
|
|
|
|
# if we have already accumulated some data let's at |
|
287
|
|
|
|
|
|
|
# least return that as a line |
|
288
|
0
|
0
|
|
|
|
0
|
length or die "$what read failed: $!"; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# no line-ending, no new bytes |
|
292
|
481
|
0
|
|
|
|
919
|
return length($_) ? substr($_, 0, length($_), "") : undef |
|
|
|
50
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
if $new_bytes==0; |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
} |
|
296
|
143
|
50
|
33
|
|
|
535
|
die "$what line too long ($pos; limit is $max_line_length)" |
|
297
|
|
|
|
|
|
|
if $max_line_length && $pos > $max_line_length; |
|
298
|
|
|
|
|
|
|
|
|
299
|
143
|
|
|
|
|
346
|
my $line = substr($_, 0, $pos+1, ""); |
|
300
|
143
|
50
|
|
|
|
770
|
$line =~ s/(\015?\012)\z// || die "Assert"; |
|
301
|
143
|
100
|
|
|
|
682
|
return wantarray ? ($line, $1) : $line; |
|
302
|
|
|
|
|
|
|
} |
|
303
|
|
|
|
|
|
|
} |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub can_read { |
|
307
|
1682
|
|
|
1682
|
0
|
2117
|
my $self = shift; |
|
308
|
1682
|
100
|
|
|
|
3788
|
return 1 unless defined(fileno($self)); |
|
309
|
1182
|
100
|
100
|
|
|
11582
|
return 1 if $self->isa('IO::Socket::SSL') && $self->pending; |
|
310
|
340
|
0
|
33
|
|
|
1253
|
return 1 if $self->isa('Net::SSL') && $self->can('pending') && $self->pending; |
|
|
|
|
33
|
|
|
|
|
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# With no timeout, wait forever. An explicit timeout of 0 can be |
|
313
|
|
|
|
|
|
|
# used to just check if the socket is readable without waiting. |
|
314
|
340
|
50
|
50
|
|
|
579
|
my $timeout = @_ ? shift : (${*$self}{io_socket_timeout} || undef); |
|
315
|
|
|
|
|
|
|
|
|
316
|
340
|
|
|
|
|
599
|
my $fbits = ''; |
|
317
|
340
|
|
|
|
|
1054
|
vec($fbits, fileno($self), 1) = 1; |
|
318
|
|
|
|
|
|
|
SELECT: |
|
319
|
|
|
|
|
|
|
{ |
|
320
|
340
|
|
|
|
|
770
|
my $before; |
|
|
340
|
|
|
|
|
416
|
|
|
321
|
340
|
50
|
|
|
|
585
|
$before = time if $timeout; |
|
322
|
340
|
|
|
|
|
376405
|
my $nfound = select($fbits, undef, undef, $timeout); |
|
323
|
340
|
50
|
|
|
|
1047
|
if ($nfound < 0) { |
|
324
|
0
|
0
|
0
|
|
|
0
|
if ($!{EINTR} || $!{EAGAIN} || $!{EWOULDBLOCK}) { |
|
|
|
|
0
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# don't really think EAGAIN/EWOULDBLOCK can happen here |
|
326
|
0
|
0
|
|
|
|
0
|
if ($timeout) { |
|
327
|
0
|
|
|
|
|
0
|
$timeout -= time - $before; |
|
328
|
0
|
0
|
|
|
|
0
|
$timeout = 0 if $timeout < 0; |
|
329
|
|
|
|
|
|
|
} |
|
330
|
0
|
|
|
|
|
0
|
redo SELECT; |
|
331
|
|
|
|
|
|
|
} |
|
332
|
0
|
|
|
|
|
0
|
die "select failed: $!"; |
|
333
|
|
|
|
|
|
|
} |
|
334
|
340
|
|
|
|
|
1198
|
return $nfound > 0; |
|
335
|
|
|
|
|
|
|
} |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub _rbuf { |
|
340
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
341
|
0
|
0
|
|
|
|
0
|
if (@_) { |
|
342
|
0
|
|
|
|
|
0
|
for (${*$self}{'http_buf'}) { |
|
|
0
|
|
|
|
|
0
|
|
|
343
|
0
|
|
|
|
|
0
|
my $old; |
|
344
|
0
|
0
|
|
|
|
0
|
$old = $_ if defined wantarray; |
|
345
|
0
|
|
|
|
|
0
|
$_ = shift; |
|
346
|
0
|
|
|
|
|
0
|
return $old; |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
else { |
|
350
|
0
|
|
|
|
|
0
|
return ${*$self}{'http_buf'}; |
|
|
0
|
|
|
|
|
0
|
|
|
351
|
|
|
|
|
|
|
} |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub _rbuf_length { |
|
355
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
356
|
0
|
|
|
|
|
0
|
return length ${*$self}{'http_buf'}; |
|
|
0
|
|
|
|
|
0
|
|
|
357
|
|
|
|
|
|
|
} |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub _read_header_lines { |
|
361
|
21
|
|
|
21
|
|
58
|
my $self = shift; |
|
362
|
21
|
|
|
|
|
48
|
my $junk_out = shift; |
|
363
|
|
|
|
|
|
|
|
|
364
|
21
|
|
|
|
|
64
|
my @headers; |
|
365
|
21
|
|
|
|
|
36
|
my $line_count = 0; |
|
366
|
21
|
|
|
|
|
42
|
my $max_header_lines = ${*$self}{'http_max_header_lines'}; |
|
|
21
|
|
|
|
|
50
|
|
|
367
|
21
|
|
|
|
|
63
|
while (my $line = my_readline($self, 'Header')) { |
|
368
|
82
|
100
|
33
|
|
|
480
|
if ($line =~ /^(\S+?)\s*:\s*(.*)/s) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
369
|
80
|
|
|
|
|
295
|
push(@headers, $1, $2); |
|
370
|
|
|
|
|
|
|
} |
|
371
|
|
|
|
|
|
|
elsif (@headers && $line =~ s/^\s+//) { |
|
372
|
0
|
|
|
|
|
0
|
$headers[-1] .= " " . $line; |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
elsif ($junk_out) { |
|
375
|
1
|
|
|
|
|
3
|
push(@$junk_out, $line); |
|
376
|
|
|
|
|
|
|
} |
|
377
|
|
|
|
|
|
|
else { |
|
378
|
1
|
|
|
|
|
9
|
die "Bad header: '$line'\n"; |
|
379
|
|
|
|
|
|
|
} |
|
380
|
81
|
50
|
|
|
|
160
|
if ($max_header_lines) { |
|
381
|
81
|
|
|
|
|
106
|
$line_count++; |
|
382
|
81
|
50
|
|
|
|
222
|
if ($line_count >= $max_header_lines) { |
|
383
|
0
|
|
|
|
|
0
|
die "Too many header lines (limit is $max_header_lines)"; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
} |
|
386
|
|
|
|
|
|
|
} |
|
387
|
20
|
|
|
|
|
97
|
return @headers; |
|
388
|
|
|
|
|
|
|
} |
|
389
|
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
sub read_response_headers { |
|
392
|
20
|
|
|
20
|
0
|
2517
|
my($self, %opt) = @_; |
|
393
|
20
|
|
|
|
|
44
|
my $laxed = $opt{laxed}; |
|
394
|
|
|
|
|
|
|
|
|
395
|
20
|
|
|
|
|
55
|
my($status, $eol) = my_readline($self, 'Status'); |
|
396
|
20
|
50
|
|
|
|
60
|
unless (defined $status) { |
|
397
|
0
|
|
|
|
|
0
|
die "Server closed connection without sending any data back"; |
|
398
|
|
|
|
|
|
|
} |
|
399
|
|
|
|
|
|
|
|
|
400
|
20
|
|
|
|
|
108
|
my($peer_ver, $code, $message) = split(/\s+/, $status, 3); |
|
401
|
20
|
100
|
66
|
|
|
237
|
if (!$peer_ver || $peer_ver !~ s,^HTTP/,, || $code !~ /^[1-5]\d\d$/) { |
|
|
|
|
66
|
|
|
|
|
|
402
|
2
|
100
|
|
|
|
12
|
die "Bad response status line: '$status'" unless $laxed; |
|
403
|
|
|
|
|
|
|
# assume HTTP/0.9 |
|
404
|
1
|
|
|
|
|
3
|
${*$self}{'http_peer_http_version'} = "0.9"; |
|
|
1
|
|
|
|
|
3
|
|
|
405
|
1
|
|
|
|
|
4
|
${*$self}{'http_status'} = "200"; |
|
|
1
|
|
|
|
|
3
|
|
|
406
|
1
|
|
50
|
|
|
5
|
substr(${*$self}{'http_buf'}, 0, 0) = $status . ($eol || ""); |
|
|
1
|
|
|
|
|
3
|
|
|
407
|
1
|
50
|
|
|
|
4
|
return 200 unless wantarray; |
|
408
|
1
|
|
|
|
|
5
|
return (200, "Assumed OK"); |
|
409
|
|
|
|
|
|
|
}; |
|
410
|
|
|
|
|
|
|
|
|
411
|
18
|
|
|
|
|
43
|
${*$self}{'http_peer_http_version'} = $peer_ver; |
|
|
18
|
|
|
|
|
85
|
|
|
412
|
18
|
|
|
|
|
34
|
${*$self}{'http_status'} = $code; |
|
|
18
|
|
|
|
|
60
|
|
|
413
|
|
|
|
|
|
|
|
|
414
|
18
|
|
|
|
|
33
|
my $junk_out; |
|
415
|
18
|
100
|
|
|
|
47
|
if ($laxed) { |
|
416
|
1
|
|
50
|
|
|
6
|
$junk_out = $opt{junk_out} || []; |
|
417
|
|
|
|
|
|
|
} |
|
418
|
18
|
|
|
|
|
104
|
my @headers = $self->_read_header_lines($junk_out); |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
# pick out headers that read_entity_body might need |
|
421
|
17
|
|
|
|
|
38
|
my @te; |
|
422
|
|
|
|
|
|
|
my $content_length; |
|
423
|
17
|
|
|
|
|
71
|
for (my $i = 0; $i < @headers; $i += 2) { |
|
424
|
76
|
|
|
|
|
142
|
my $h = lc($headers[$i]); |
|
425
|
76
|
100
|
|
|
|
243
|
if ($h eq 'transfer-encoding') { |
|
|
|
100
|
|
|
|
|
|
|
426
|
4
|
|
|
|
|
7
|
my $te = $headers[$i+1]; |
|
427
|
4
|
|
|
|
|
14
|
$te =~ s/^\s+//; |
|
428
|
4
|
|
|
|
|
9
|
$te =~ s/\s+$//; |
|
429
|
4
|
50
|
|
|
|
15
|
push(@te, $te) if length($te); |
|
430
|
|
|
|
|
|
|
} |
|
431
|
|
|
|
|
|
|
elsif ($h eq 'content-length') { |
|
432
|
|
|
|
|
|
|
# ignore bogus and overflow values |
|
433
|
12
|
50
|
|
|
|
96
|
if ($headers[$i+1] =~ /^\s*(\d{1,15})(?:\s|$)/) { |
|
434
|
12
|
|
|
|
|
53
|
$content_length = $1; |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
} |
|
437
|
|
|
|
|
|
|
} |
|
438
|
17
|
|
|
|
|
59
|
${*$self}{'http_te'} = join(",", @te); |
|
|
17
|
|
|
|
|
52
|
|
|
439
|
17
|
|
|
|
|
36
|
${*$self}{'http_content_length'} = $content_length; |
|
|
17
|
|
|
|
|
45
|
|
|
440
|
17
|
|
|
|
|
36
|
${*$self}{'http_first_body'}++; |
|
|
17
|
|
|
|
|
50
|
|
|
441
|
17
|
|
|
|
|
31
|
delete ${*$self}{'http_trailers'}; |
|
|
17
|
|
|
|
|
40
|
|
|
442
|
17
|
50
|
|
|
|
70
|
return $code unless wantarray; |
|
443
|
17
|
|
|
|
|
176
|
return ($code, $message, @headers); |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
sub read_entity_body { |
|
448
|
1305
|
|
|
1305
|
0
|
7933
|
my $self = shift; |
|
449
|
1305
|
|
|
|
|
1759
|
my $buf_ref = \$_[0]; |
|
450
|
1305
|
|
|
|
|
1640
|
my $size = $_[1]; |
|
451
|
1305
|
50
|
|
|
|
2217
|
die "Offset not supported yet" if $_[2]; |
|
452
|
|
|
|
|
|
|
|
|
453
|
1305
|
|
|
|
|
1730
|
my $chunked; |
|
454
|
|
|
|
|
|
|
my $bytes; |
|
455
|
|
|
|
|
|
|
|
|
456
|
1305
|
100
|
|
|
|
1474
|
if (${*$self}{'http_first_body'}) { |
|
|
1305
|
|
|
|
|
2843
|
|
|
457
|
17
|
|
|
|
|
27
|
${*$self}{'http_first_body'} = 0; |
|
|
17
|
|
|
|
|
37
|
|
|
458
|
17
|
|
|
|
|
32
|
delete ${*$self}{'http_chunked'}; |
|
|
17
|
|
|
|
|
46
|
|
|
459
|
17
|
|
|
|
|
31
|
delete ${*$self}{'http_bytes'}; |
|
|
17
|
|
|
|
|
32
|
|
|
460
|
17
|
|
|
|
|
42
|
my $method = shift(@{${*$self}{'http_request_method'}}); |
|
|
17
|
|
|
|
|
24
|
|
|
|
17
|
|
|
|
|
61
|
|
|
461
|
17
|
|
|
|
|
34
|
my $status = ${*$self}{'http_status'}; |
|
|
17
|
|
|
|
|
37
|
|
|
462
|
17
|
100
|
|
|
|
46
|
if ($method eq "HEAD") { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# this response is always empty regardless of other headers |
|
464
|
1
|
|
|
|
|
3
|
$bytes = 0; |
|
465
|
|
|
|
|
|
|
} |
|
466
|
16
|
|
|
|
|
49
|
elsif (my $te = ${*$self}{'http_te'}) { |
|
467
|
3
|
|
|
|
|
15
|
my @te = split(/\s*,\s*/, lc($te)); |
|
468
|
3
|
50
|
|
|
|
10
|
die "Chunked must be last Transfer-Encoding '$te'" |
|
469
|
|
|
|
|
|
|
unless pop(@te) eq "chunked"; |
|
470
|
3
|
|
66
|
|
|
24
|
pop(@te) while @te && $te[-1] eq "chunked"; # ignore repeated chunked spec |
|
471
|
|
|
|
|
|
|
|
|
472
|
3
|
|
|
|
|
9
|
for (@te) { |
|
473
|
0
|
0
|
0
|
|
|
0
|
if ($_ eq "deflate" && inflate_ok()) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
#require Compress::Raw::Zlib; |
|
475
|
0
|
|
|
|
|
0
|
my ($i, $status) = Compress::Raw::Zlib::Inflate->new(); |
|
476
|
0
|
0
|
|
|
|
0
|
die "Can't make inflator: $status" unless $i; |
|
477
|
0
|
|
|
0
|
|
0
|
$_ = sub { my $out; $i->inflate($_[0], \$out); $out } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
478
|
0
|
|
|
|
|
0
|
} |
|
479
|
|
|
|
|
|
|
elsif ($_ eq "gzip" && gunzip_ok()) { |
|
480
|
|
|
|
|
|
|
#require IO::Uncompress::Gunzip; |
|
481
|
0
|
|
|
|
|
0
|
my @buf; |
|
482
|
|
|
|
|
|
|
$_ = sub { |
|
483
|
0
|
|
|
0
|
|
0
|
push(@buf, $_[0]); |
|
484
|
0
|
0
|
|
|
|
0
|
return "" unless $_[1]; |
|
485
|
0
|
|
|
|
|
0
|
my $input = join("", @buf); |
|
486
|
0
|
|
|
|
|
0
|
my $output; |
|
487
|
0
|
0
|
|
|
|
0
|
IO::Uncompress::Gunzip::gunzip(\$input, \$output, Transparent => 0) |
|
488
|
|
|
|
|
|
|
or die "Can't gunzip content: $IO::Uncompress::Gunzip::GunzipError"; |
|
489
|
0
|
|
|
|
|
0
|
return \$output; |
|
490
|
0
|
|
|
|
|
0
|
}; |
|
491
|
|
|
|
|
|
|
} |
|
492
|
|
|
|
|
|
|
elsif ($_ eq "identity") { |
|
493
|
0
|
|
|
0
|
|
0
|
$_ = sub { $_[0] }; |
|
|
0
|
|
|
|
|
0
|
|
|
494
|
|
|
|
|
|
|
} |
|
495
|
|
|
|
|
|
|
else { |
|
496
|
0
|
|
|
|
|
0
|
die "Can't handle transfer encoding '$te'"; |
|
497
|
|
|
|
|
|
|
} |
|
498
|
|
|
|
|
|
|
} |
|
499
|
|
|
|
|
|
|
|
|
500
|
3
|
|
|
|
|
4
|
@te = reverse(@te); |
|
501
|
|
|
|
|
|
|
|
|
502
|
3
|
50
|
|
|
|
8
|
${*$self}{'http_te2'} = @te ? \@te : ""; |
|
|
3
|
|
|
|
|
7
|
|
|
503
|
3
|
|
|
|
|
9
|
$chunked = -1; |
|
504
|
|
|
|
|
|
|
} |
|
505
|
13
|
|
|
|
|
59
|
elsif (defined(my $content_length = ${*$self}{'http_content_length'})) { |
|
506
|
11
|
|
|
|
|
28
|
$bytes = $content_length; |
|
507
|
|
|
|
|
|
|
} |
|
508
|
|
|
|
|
|
|
elsif ($status =~ /^(?:1|[23]04)/) { |
|
509
|
|
|
|
|
|
|
# RFC 2616 says that these responses should always be empty |
|
510
|
|
|
|
|
|
|
# but that does not appear to be true in practice [RT#17907] |
|
511
|
0
|
|
|
|
|
0
|
$bytes = 0; |
|
512
|
|
|
|
|
|
|
} |
|
513
|
|
|
|
|
|
|
else { |
|
514
|
|
|
|
|
|
|
# XXX Multi-Part types are self delimiting, but RFC 2616 says we |
|
515
|
|
|
|
|
|
|
# only has to deal with 'multipart/byteranges' |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
# Read until EOF |
|
518
|
|
|
|
|
|
|
} |
|
519
|
|
|
|
|
|
|
} |
|
520
|
|
|
|
|
|
|
else { |
|
521
|
1288
|
|
|
|
|
1576
|
$chunked = ${*$self}{'http_chunked'}; |
|
|
1288
|
|
|
|
|
2171
|
|
|
522
|
1288
|
|
|
|
|
1724
|
$bytes = ${*$self}{'http_bytes'}; |
|
|
1288
|
|
|
|
|
2172
|
|
|
523
|
|
|
|
|
|
|
} |
|
524
|
|
|
|
|
|
|
|
|
525
|
1305
|
100
|
|
|
|
2763
|
if (defined $chunked) { |
|
|
|
100
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
# The state encoded in $chunked is: |
|
527
|
|
|
|
|
|
|
# $chunked == 0: read CRLF after chunk, then chunk header |
|
528
|
|
|
|
|
|
|
# $chunked == -1: read chunk header |
|
529
|
|
|
|
|
|
|
# $chunked > 0: bytes left in current chunk to read |
|
530
|
|
|
|
|
|
|
|
|
531
|
18
|
100
|
|
|
|
43
|
if ($chunked <= 0) { |
|
532
|
12
|
|
|
|
|
20
|
my $line = my_readline($self, 'Entity body'); |
|
533
|
12
|
100
|
|
|
|
51
|
if ($chunked == 0) { |
|
534
|
9
|
50
|
33
|
|
|
57
|
die "Missing newline after chunk data: '$line'" |
|
535
|
|
|
|
|
|
|
if !defined($line) || $line ne ""; |
|
536
|
9
|
|
|
|
|
20
|
$line = my_readline($self, 'Entity body'); |
|
537
|
|
|
|
|
|
|
} |
|
538
|
12
|
50
|
|
|
|
28
|
die "EOF when chunk header expected" unless defined($line); |
|
539
|
12
|
|
|
|
|
20
|
my $chunk_len = $line; |
|
540
|
12
|
|
|
|
|
29
|
$chunk_len =~ s/;.*//; # ignore potential chunk parameters |
|
541
|
12
|
50
|
|
|
|
44
|
unless ($chunk_len =~ /^([\da-fA-F]+)\s*$/) { |
|
542
|
0
|
|
|
|
|
0
|
die "Bad chunk-size in HTTP response: $line"; |
|
543
|
|
|
|
|
|
|
} |
|
544
|
12
|
|
|
|
|
29
|
$chunked = hex($1); |
|
545
|
12
|
|
|
|
|
17
|
${*$self}{'http_chunked'} = $chunked; |
|
|
12
|
|
|
|
|
28
|
|
|
546
|
12
|
100
|
|
|
|
36
|
if ($chunked == 0) { |
|
547
|
3
|
|
|
|
|
8
|
${*$self}{'http_trailers'} = [$self->_read_header_lines]; |
|
|
3
|
|
|
|
|
9
|
|
|
548
|
3
|
|
|
|
|
8
|
$$buf_ref = ""; |
|
549
|
|
|
|
|
|
|
|
|
550
|
3
|
|
|
|
|
4
|
my $n = 0; |
|
551
|
3
|
50
|
|
|
|
5
|
if (my $transforms = delete ${*$self}{'http_te2'}) { |
|
|
3
|
|
|
|
|
11
|
|
|
552
|
0
|
|
|
|
|
0
|
for (@$transforms) { |
|
553
|
0
|
|
|
|
|
0
|
$$buf_ref = &$_($$buf_ref, 1); |
|
554
|
|
|
|
|
|
|
} |
|
555
|
0
|
|
|
|
|
0
|
$n = length($$buf_ref); |
|
556
|
|
|
|
|
|
|
} |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
# in case somebody tries to read more, make sure we continue |
|
559
|
|
|
|
|
|
|
# to return EOF |
|
560
|
3
|
|
|
|
|
6
|
delete ${*$self}{'http_chunked'}; |
|
|
3
|
|
|
|
|
7
|
|
|
561
|
3
|
|
|
|
|
5
|
${*$self}{'http_bytes'} = 0; |
|
|
3
|
|
|
|
|
16
|
|
|
562
|
|
|
|
|
|
|
|
|
563
|
3
|
|
|
|
|
12
|
return $n; |
|
564
|
|
|
|
|
|
|
} |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
|
|
567
|
15
|
|
|
|
|
19
|
my $n = $chunked; |
|
568
|
15
|
50
|
33
|
|
|
48
|
$n = $size if $size && $size < $n; |
|
569
|
15
|
|
|
|
|
31
|
$n = my_read($self, $$buf_ref, $n); |
|
570
|
15
|
50
|
|
|
|
209
|
return undef unless defined $n; |
|
571
|
|
|
|
|
|
|
|
|
572
|
15
|
|
|
|
|
25
|
${*$self}{'http_chunked'} = $chunked - $n; |
|
|
15
|
|
|
|
|
25
|
|
|
573
|
|
|
|
|
|
|
|
|
574
|
15
|
50
|
|
|
|
33
|
if ($n > 0) { |
|
575
|
15
|
50
|
|
|
|
19
|
if (my $transforms = ${*$self}{'http_te2'}) { |
|
|
15
|
|
|
|
|
36
|
|
|
576
|
0
|
|
|
|
|
0
|
for (@$transforms) { |
|
577
|
0
|
|
|
|
|
0
|
$$buf_ref = &$_($$buf_ref, 0); |
|
578
|
|
|
|
|
|
|
} |
|
579
|
0
|
|
|
|
|
0
|
$n = length($$buf_ref); |
|
580
|
0
|
0
|
|
|
|
0
|
$n = -1 if $n == 0; |
|
581
|
|
|
|
|
|
|
} |
|
582
|
|
|
|
|
|
|
} |
|
583
|
15
|
|
|
|
|
30
|
return $n; |
|
584
|
|
|
|
|
|
|
} |
|
585
|
|
|
|
|
|
|
elsif (defined $bytes) { |
|
586
|
1282
|
100
|
|
|
|
2056
|
unless ($bytes) { |
|
587
|
12
|
|
|
|
|
26
|
$$buf_ref = ""; |
|
588
|
12
|
|
|
|
|
28
|
return 0; |
|
589
|
|
|
|
|
|
|
} |
|
590
|
1270
|
|
|
|
|
1639
|
my $n = $bytes; |
|
591
|
1270
|
100
|
66
|
|
|
3675
|
$n = $size if $size && $size < $n; |
|
592
|
1270
|
|
|
|
|
2013
|
$n = my_read($self, $$buf_ref, $n); |
|
593
|
1270
|
100
|
|
|
|
27729
|
${*$self}{'http_bytes'} = defined $n ? $bytes - $n : $bytes; |
|
|
1270
|
|
|
|
|
2627
|
|
|
594
|
1270
|
|
|
|
|
2707
|
return $n; |
|
595
|
|
|
|
|
|
|
} |
|
596
|
|
|
|
|
|
|
else { |
|
597
|
|
|
|
|
|
|
# read until eof |
|
598
|
5
|
|
50
|
|
|
12
|
$size ||= 8*1024; |
|
599
|
5
|
|
|
|
|
12
|
return my_read($self, $$buf_ref, $size); |
|
600
|
|
|
|
|
|
|
} |
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub get_trailers { |
|
604
|
13
|
|
|
13
|
0
|
79
|
my $self = shift; |
|
605
|
13
|
100
|
|
|
|
18
|
@{${*$self}{'http_trailers'} || []}; |
|
|
13
|
|
|
|
|
15
|
|
|
|
13
|
|
|
|
|
89
|
|
|
606
|
|
|
|
|
|
|
} |
|
607
|
|
|
|
|
|
|
|
|
608
|
0
|
|
|
|
|
0
|
BEGIN { |
|
609
|
5
|
|
|
5
|
|
2674
|
my $gunzip_ok; |
|
610
|
5
|
|
|
|
|
188
|
my $inflate_ok; |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
sub gunzip_ok { |
|
613
|
0
|
0
|
|
0
|
0
|
0
|
return $gunzip_ok if defined $gunzip_ok; |
|
614
|
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
# Try to load IO::Uncompress::Gunzip. |
|
616
|
0
|
|
|
|
|
0
|
local $@; |
|
617
|
0
|
|
|
|
|
0
|
local $SIG{__DIE__}; |
|
618
|
0
|
|
|
|
|
0
|
$gunzip_ok = 0; |
|
619
|
|
|
|
|
|
|
|
|
620
|
0
|
|
|
|
|
0
|
eval { |
|
621
|
0
|
|
|
|
|
0
|
require IO::Uncompress::Gunzip; |
|
622
|
0
|
|
|
|
|
0
|
$gunzip_ok++; |
|
623
|
|
|
|
|
|
|
}; |
|
624
|
|
|
|
|
|
|
|
|
625
|
0
|
|
|
|
|
0
|
return $gunzip_ok; |
|
626
|
|
|
|
|
|
|
} |
|
627
|
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
sub inflate_ok { |
|
629
|
0
|
0
|
|
0
|
0
|
0
|
return $inflate_ok if defined $inflate_ok; |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# Try to load Compress::Raw::Zlib. |
|
632
|
0
|
|
|
|
|
0
|
local $@; |
|
633
|
0
|
|
|
|
|
0
|
local $SIG{__DIE__}; |
|
634
|
0
|
|
|
|
|
0
|
$inflate_ok = 0; |
|
635
|
|
|
|
|
|
|
|
|
636
|
0
|
|
|
|
|
0
|
eval { |
|
637
|
0
|
|
|
|
|
0
|
require Compress::Raw::Zlib; |
|
638
|
0
|
|
|
|
|
0
|
$inflate_ok++; |
|
639
|
|
|
|
|
|
|
}; |
|
640
|
|
|
|
|
|
|
|
|
641
|
0
|
|
|
|
|
0
|
return $inflate_ok; |
|
642
|
|
|
|
|
|
|
} |
|
643
|
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
} # BEGIN |
|
645
|
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
1; |
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
=pod |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
=encoding UTF-8 |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
=head1 NAME |
|
653
|
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
Net::HTTP::Methods - Methods shared by Net::HTTP and Net::HTTPS |
|
655
|
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=head1 VERSION |
|
657
|
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
version 6.23 |
|
659
|
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
=head1 AUTHOR |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Gisle Aas |
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
665
|
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
This software is copyright (c) 2001 by Gisle Aas. |
|
667
|
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
669
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=cut |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
__END__ |