| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Net::HTTP::Methods; | 
| 2 |  |  |  |  |  |  | our $VERSION = '6.21'; | 
| 3 | 5 |  |  | 5 |  | 58725 | use strict; | 
|  | 5 |  |  |  |  | 20 |  | 
|  | 5 |  |  |  |  | 141 |  | 
| 4 | 5 |  |  | 5 |  | 23 | use warnings; | 
|  | 5 |  |  |  |  | 7 |  | 
|  | 5 |  |  |  |  | 119 |  | 
| 5 | 5 |  |  | 5 |  | 2668 | use URI; | 
|  | 5 |  |  |  |  | 27171 |  | 
|  | 5 |  |  |  |  | 2953 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | my $CRLF = "\015\012";   # "\r\n" is not portable | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | *_bytes = defined(&utf8::downgrade) ? | 
| 10 |  |  |  |  |  |  | sub { | 
| 11 | 20 | 50 |  | 20 |  | 73 | 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 |  |  |  |  | 100 | return $_[0]; | 
| 16 |  |  |  |  |  |  | } | 
| 17 |  |  |  |  |  |  | : | 
| 18 |  |  |  |  |  |  | sub { | 
| 19 |  |  |  |  |  |  | return $_[0]; | 
| 20 |  |  |  |  |  |  | }; | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | sub new { | 
| 24 | 5 |  |  | 5 | 0 | 4028 | my $class = shift; | 
| 25 | 5 | 100 |  |  |  | 23 | unshift(@_, "Host") if @_ == 1; | 
| 26 | 5 |  |  |  |  | 20 | my %cnf = @_; | 
| 27 | 5 |  |  |  |  | 427 | require Symbol; | 
| 28 | 5 |  |  |  |  | 613 | my $self = bless Symbol::gensym(), $class; | 
| 29 | 5 |  |  |  |  | 88 | return $self->http_configure(\%cnf); | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | sub http_configure { | 
| 33 | 8 |  |  | 8 | 0 | 29 | my($self, $cnf) = @_; | 
| 34 |  |  |  |  |  |  |  | 
| 35 | 8 | 50 |  |  |  | 29 | die "Listen option not allowed" if $cnf->{Listen}; | 
| 36 | 8 |  |  |  |  | 20 | my $explicit_host = (exists $cnf->{Host}); | 
| 37 | 8 |  |  |  |  | 14 | my $host = delete $cnf->{Host}; | 
| 38 |  |  |  |  |  |  | # All this because $cnf->{PeerAddr} = 0 is actually valid. | 
| 39 | 8 |  |  |  |  | 17 | my $peer; | 
| 40 | 8 |  |  |  |  | 18 | for my $key (qw{PeerAddr PeerHost}) { | 
| 41 | 14 | 100 | 66 |  |  | 57 | next if !defined($cnf->{$key}) || q{} eq $cnf->{$key}; | 
| 42 | 2 |  |  |  |  | 6 | $peer = $cnf->{$key}; | 
| 43 | 2 |  |  |  |  | 6 | last; | 
| 44 |  |  |  |  |  |  | } | 
| 45 | 8 | 100 |  |  |  | 68 | if (!defined $peer) { | 
| 46 | 6 | 50 |  |  |  | 18 | 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 |  |  |  |  | 55 | my $peer_uri = URI->new("http://$peer"); | 
| 53 | 8 |  | 66 |  |  | 28693 | $cnf->{"PeerPort"} =  $peer_uri->_port || $cnf->{PeerPort} ||  $self->http_default_port; | 
| 54 | 8 |  |  |  |  | 156 | $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 |  |  | 247 | if (($host) || (! $explicit_host)) { | 
| 63 | 7 | 100 |  |  |  | 49 | my $uri =  ($explicit_host) ? URI->new("http://$host") : $peer_uri->clone; | 
| 64 | 7 | 100 |  |  |  | 347 | if (!$uri->_port) { | 
| 65 |  |  |  |  |  |  | # Always use *our*  $self->http_default_port  instead of URI's  (Covers HTTP, HTTPS) | 
| 66 | 6 |  | 33 |  |  | 120 | $uri->port( $cnf->{PeerPort} ||  $self->http_default_port); | 
| 67 |  |  |  |  |  |  | } | 
| 68 | 7 |  |  |  |  | 396 | my $host_port = $uri->host_port;               # Returns host:port or [ipv6]:port | 
| 69 | 7 |  |  |  |  | 160 | my $remove = ":" . $self->http_default_port;   # we want to remove the default port number | 
| 70 | 7 | 100 |  |  |  | 33 | if (substr($host_port,0-length($remove)) eq $remove) { | 
| 71 | 5 |  |  |  |  | 13 | substr($host_port,0-length($remove)) = ""; | 
| 72 |  |  |  |  |  |  | } | 
| 73 | 7 |  |  |  |  | 32 | $host = $host_port; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 8 |  |  |  |  | 21 | $cnf->{Proto} = 'tcp'; | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 8 |  |  |  |  | 19 | my $keep_alive = delete $cnf->{KeepAlive}; | 
| 79 | 8 |  |  |  |  | 15 | my $http_version = delete $cnf->{HTTPVersion}; | 
| 80 | 8 | 50 |  |  |  | 22 | $http_version = "1.1" unless defined $http_version; | 
| 81 | 8 |  |  |  |  | 14 | my $peer_http_version = delete $cnf->{PeerHTTPVersion}; | 
| 82 | 8 | 100 |  |  |  | 20 | $peer_http_version = "1.0" unless defined $peer_http_version; | 
| 83 | 8 |  |  |  |  | 16 | my $send_te = delete $cnf->{SendTE}; | 
| 84 | 8 |  |  |  |  | 14 | my $max_line_length = delete $cnf->{MaxLineLength}; | 
| 85 | 8 | 100 |  |  |  | 17 | $max_line_length = 8*1024 unless defined $max_line_length; | 
| 86 | 8 |  |  |  |  | 12 | my $max_header_lines = delete $cnf->{MaxHeaderLines}; | 
| 87 | 8 | 50 |  |  |  | 19 | $max_header_lines = 128 unless defined $max_header_lines; | 
| 88 |  |  |  |  |  |  |  | 
| 89 | 8 | 100 |  |  |  | 31 | return undef unless $self->http_connect($cnf); | 
| 90 |  |  |  |  |  |  |  | 
| 91 | 7 |  |  |  |  | 255041 | $self->host($host); | 
| 92 | 7 |  |  |  |  | 35 | $self->keep_alive($keep_alive); | 
| 93 | 7 |  |  |  |  | 30 | $self->send_te($send_te); | 
| 94 | 7 |  |  |  |  | 33 | $self->http_version($http_version); | 
| 95 | 7 |  |  |  |  | 35 | $self->peer_http_version($peer_http_version); | 
| 96 | 7 |  |  |  |  | 35 | $self->max_line_length($max_line_length); | 
| 97 | 7 |  |  |  |  | 35 | $self->max_header_lines($max_header_lines); | 
| 98 |  |  |  |  |  |  |  | 
| 99 | 7 |  |  |  |  | 14 | ${*$self}{'http_buf'} = ""; | 
|  | 7 |  |  |  |  | 15 |  | 
| 100 |  |  |  |  |  |  |  | 
| 101 | 7 |  |  |  |  | 56 | return $self; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | sub http_default_port { | 
| 105 | 11 |  |  | 11 | 0 | 309 | 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 |  | 42 | no strict 'refs'; | 
|  | 5 |  |  |  |  | 26 |  | 
|  | 5 |  |  |  |  | 15399 |  | 
| 112 |  |  |  |  |  |  | *$method = sub { | 
| 113 | 85 |  |  | 85 |  | 2292 | my $self = shift; | 
| 114 | 85 |  |  |  |  | 94 | my $old = ${*$self}{$prop_name}; | 
|  | 85 |  |  |  |  | 185 |  | 
| 115 | 85 | 100 |  |  |  | 166 | ${*$self}{$prop_name} = shift if @_; | 
|  | 43 |  |  |  |  | 84 |  | 
| 116 | 85 |  |  |  |  | 173 | return $old; | 
| 117 |  |  |  |  |  |  | }; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | # we want this one to be a bit smarter | 
| 121 |  |  |  |  |  |  | sub http_version { | 
| 122 | 8 |  |  | 8 | 0 | 18 | my $self = shift; | 
| 123 | 8 |  |  |  |  | 10 | my $old = ${*$self}{'http_version'}; | 
|  | 8 |  |  |  |  | 18 |  | 
| 124 | 8 | 50 |  |  |  | 24 | if (@_) { | 
| 125 | 8 |  |  |  |  | 13 | my $v = shift; | 
| 126 | 8 | 50 |  |  |  | 23 | $v = "1.0" if $v eq "1";  # float | 
| 127 | 8 | 50 | 66 |  |  | 52 | 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 |  |  |  |  | 12 | ${*$self}{'http_version'} = $v; | 
|  | 8 |  |  |  |  | 25 |  | 
| 132 |  |  |  |  |  |  | } | 
| 133 | 8 |  |  |  |  | 15 | $old; | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | sub format_request { | 
| 137 | 20 |  |  | 20 | 0 | 31 | my $self = shift; | 
| 138 | 20 |  |  |  |  | 26 | my $method = shift; | 
| 139 | 20 |  |  |  |  | 34 | my $uri = shift; | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 20 | 50 |  |  |  | 65 | my $content = (@_ % 2) ? pop : ""; | 
| 142 |  |  |  |  |  |  |  | 
| 143 | 20 |  |  |  |  | 44 | for ($method, $uri) { | 
| 144 | 40 |  |  |  |  | 174 | require Carp; | 
| 145 | 40 | 50 | 33 |  |  | 199 | Carp::croak("Bad method or uri") if /\s/ || !length; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 | 20 |  |  |  |  | 31 | push(@{${*$self}{'http_request_method'}}, $method); | 
|  | 20 |  |  |  |  | 26 |  | 
|  | 20 |  |  |  |  | 88 |  | 
| 149 | 20 |  |  |  |  | 29 | my $ver = ${*$self}{'http_version'}; | 
|  | 20 |  |  |  |  | 43 |  | 
| 150 | 20 |  | 50 |  |  | 30 | my $peer_ver = ${*$self}{'http_peer_http_version'} || "1.0"; | 
| 151 |  |  |  |  |  |  |  | 
| 152 | 20 |  |  |  |  | 33 | my @h; | 
| 153 |  |  |  |  |  |  | my @connection; | 
| 154 | 20 |  |  |  |  | 69 | my %given = (host => 0, "content-length" => 0, "te" => 0); | 
| 155 | 20 |  |  |  |  | 48 | while (@_) { | 
| 156 | 12 |  |  |  |  | 30 | my($k, $v) = splice(@_, 0, 2); | 
| 157 | 12 |  |  |  |  | 26 | my $lc_k = lc($k); | 
| 158 | 12 | 50 |  |  |  | 31 | 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 |  |  |  | 26 | if (exists $given{$lc_k}) { | 
| 165 | 0 |  |  |  |  | 0 | $given{$lc_k}++; | 
| 166 |  |  |  |  |  |  | } | 
| 167 | 12 |  |  |  |  | 44 | push(@h, "$k: $v"); | 
| 168 |  |  |  |  |  |  | } | 
| 169 |  |  |  |  |  |  |  | 
| 170 | 20 | 50 | 33 |  |  | 62 | if (length($content) && !$given{'content-length'}) { | 
| 171 | 0 |  |  |  |  | 0 | push(@h, "Content-Length: " . length($content)); | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  |  | 
| 174 | 20 |  |  |  |  | 33 | my @h2; | 
| 175 | 20 | 50 | 33 |  |  | 61 | 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 |  |  |  | 70 | unless (grep lc($_) eq "close", @connection) { | 
| 186 | 20 | 100 |  |  |  | 43 | if ($self->keep_alive) { | 
| 187 | 12 | 100 |  |  |  | 34 | if ($peer_ver eq "1.0") { | 
| 188 |  |  |  |  |  |  | # from looking at Netscape's headers | 
| 189 | 4 |  |  |  |  | 6 | push(@h2, "Keep-Alive: 300"); | 
| 190 | 4 |  |  |  |  | 9 | unshift(@connection, "Keep-Alive"); | 
| 191 |  |  |  |  |  |  | } | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  | else { | 
| 194 | 8 | 100 |  |  |  | 25 | push(@connection, "close") if $ver ge "1.1"; | 
| 195 |  |  |  |  |  |  | } | 
| 196 |  |  |  |  |  |  | } | 
| 197 | 20 | 100 |  |  |  | 66 | push(@h2, "Connection: " . join(", ", @connection)) if @connection; | 
| 198 | 20 | 50 |  |  |  | 45 | unless ($given{host}) { | 
| 199 | 20 |  |  |  |  | 28 | my $h = ${*$self}{'http_host'}; | 
|  | 20 |  |  |  |  | 40 |  | 
| 200 | 20 | 100 |  |  |  | 61 | push(@h2, "Host: $h") if $h; | 
| 201 |  |  |  |  |  |  | } | 
| 202 |  |  |  |  |  |  |  | 
| 203 | 20 |  |  |  |  | 103 | return _bytes(join($CRLF, "$method $uri HTTP/$ver", @h2, @h, "", $content)); | 
| 204 |  |  |  |  |  |  | } | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | sub write_request { | 
| 208 | 20 |  |  | 20 | 0 | 16070 | my $self = shift; | 
| 209 | 20 |  |  |  |  | 75 | $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 | 1138 | 50 |  | 1138 | 0 | 1874 | die if @_ > 3; | 
| 241 | 1138 |  |  |  |  | 1349 | my $self = shift; | 
| 242 | 1138 |  |  |  |  | 1311 | my $len = $_[1]; | 
| 243 | 1138 |  |  |  |  | 1284 | for (${*$self}{'http_buf'}) { | 
|  | 1138 |  |  |  |  | 2332 |  | 
| 244 | 1138 | 100 |  |  |  | 1771 | if (length) { | 
| 245 | 64 |  |  |  |  | 98 | $_[0] = substr($_, 0, $len, ""); | 
| 246 | 64 |  |  |  |  | 147 | return length($_[0]); | 
| 247 |  |  |  |  |  |  | } | 
| 248 |  |  |  |  |  |  | else { | 
| 249 | 1074 | 50 |  |  |  | 1658 | die "read timeout" unless $self->can_read; | 
| 250 | 1074 |  |  |  |  | 9845 | return $self->sysread($_[0], $len); | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  | } | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | sub my_readline { | 
| 257 | 151 |  |  | 151 | 0 | 194 | my $self = shift; | 
| 258 | 151 |  |  |  |  | 172 | my $what = shift; | 
| 259 | 151 |  |  |  |  | 185 | for (${*$self}{'http_buf'}) { | 
|  | 151 |  |  |  |  | 334 |  | 
| 260 | 151 |  |  |  |  | 172 | my $max_line_length = ${*$self}{'http_max_line_length'}; | 
|  | 151 |  |  |  |  | 230 |  | 
| 261 | 151 |  |  |  |  | 184 | my $pos; | 
| 262 | 151 |  |  |  |  | 186 | while (1) { | 
| 263 |  |  |  |  |  |  | # find line ending | 
| 264 | 632 |  |  |  |  | 750 | $pos = index($_, "\012"); | 
| 265 | 632 | 100 |  |  |  | 885 | last if $pos >= 0; | 
| 266 | 481 | 50 | 33 |  |  | 1182 | 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 |  |  |  |  | 499 | my $new_bytes = 0; | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | READ: | 
| 273 |  |  |  |  |  |  | {   # wait until bytes start arriving | 
| 274 | 481 | 50 |  |  |  | 463 | $self->can_read | 
|  | 481 |  |  |  |  | 665 |  | 
| 275 |  |  |  |  |  |  | or die "read timeout"; | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | # consume all incoming bytes | 
| 278 | 481 |  |  |  |  | 831 | my $bytes_read = $self->sysread($_, 1024, length); | 
| 279 | 481 | 50 | 0 |  |  | 5632 | if(defined $bytes_read) { | 
|  |  | 0 | 0 |  |  |  |  | 
| 280 | 481 |  |  |  |  | 504 | $new_bytes += $bytes_read; | 
| 281 |  |  |  |  |  |  | } | 
| 282 | 1 |  |  | 1 |  | 458 | elsif($!{EINTR} || $!{EAGAIN} || $!{EWOULDBLOCK}) { | 
|  | 1 |  |  |  |  | 1210 |  | 
|  | 1 |  |  |  |  | 7 |  | 
| 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 |  |  |  | 764 | return length($_) ? substr($_, 0, length($_), "") : undef | 
|  |  | 50 |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | if $new_bytes==0; | 
| 294 |  |  |  |  |  |  | } | 
| 295 |  |  |  |  |  |  | } | 
| 296 | 151 | 50 | 33 |  |  | 441 | die "$what line too long ($pos; limit is $max_line_length)" | 
| 297 |  |  |  |  |  |  | if $max_line_length && $pos > $max_line_length; | 
| 298 |  |  |  |  |  |  |  | 
| 299 | 151 |  |  |  |  | 325 | my $line = substr($_, 0, $pos+1, ""); | 
| 300 | 151 | 50 |  |  |  | 694 | $line =~ s/(\015?\012)\z// || die "Assert"; | 
| 301 | 151 | 100 |  |  |  | 575 | return wantarray ? ($line, $1) : $line; | 
| 302 |  |  |  |  |  |  | } | 
| 303 |  |  |  |  |  |  | } | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | sub can_read { | 
| 307 | 1552 |  |  | 1552 | 0 | 1880 | my $self = shift; | 
| 308 | 1552 | 100 |  |  |  | 3223 | return 1 unless defined(fileno($self)); | 
| 309 | 1052 | 100 | 100 |  |  | 10745 | return 1 if $self->isa('IO::Socket::SSL') && $self->pending; | 
| 310 | 218 | 0 | 33 |  |  | 703 | 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 | 218 | 50 | 50 |  |  | 307 | my $timeout = @_ ? shift : (${*$self}{io_socket_timeout} || undef); | 
| 315 |  |  |  |  |  |  |  | 
| 316 | 218 |  |  |  |  | 290 | my $fbits = ''; | 
| 317 | 218 |  |  |  |  | 482 | vec($fbits, fileno($self), 1) = 1; | 
| 318 |  |  |  |  |  |  | SELECT: | 
| 319 |  |  |  |  |  |  | { | 
| 320 | 218 |  |  |  |  | 486 | my $before; | 
|  | 218 |  |  |  |  | 236 |  | 
| 321 | 218 | 50 |  |  |  | 325 | $before = time if $timeout; | 
| 322 | 218 |  |  |  |  | 65656 | my $nfound = select($fbits, undef, undef, $timeout); | 
| 323 | 218 | 50 |  |  |  | 525 | 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 | 218 |  |  |  |  | 578 | 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 |  | 33 | my $self = shift; | 
| 362 | 21 |  |  |  |  | 27 | my $junk_out = shift; | 
| 363 |  |  |  |  |  |  |  | 
| 364 | 21 |  |  |  |  | 56 | my @headers; | 
| 365 | 21 |  |  |  |  | 32 | my $line_count = 0; | 
| 366 | 21 |  |  |  |  | 27 | my $max_header_lines = ${*$self}{'http_max_header_lines'}; | 
|  | 21 |  |  |  |  | 38 |  | 
| 367 | 21 |  |  |  |  | 60 | while (my $line = my_readline($self, 'Header')) { | 
| 368 | 90 | 100 | 33 |  |  | 378 | if ($line =~ /^(\S+?)\s*:\s*(.*)/s) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 369 | 88 |  |  |  |  | 270 | 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 |  |  |  |  | 8 | die "Bad header: '$line'\n"; | 
| 379 |  |  |  |  |  |  | } | 
| 380 | 89 | 50 |  |  |  | 154 | if ($max_header_lines) { | 
| 381 | 89 |  |  |  |  | 97 | $line_count++; | 
| 382 | 89 | 50 |  |  |  | 205 | if ($line_count >= $max_header_lines) { | 
| 383 | 0 |  |  |  |  | 0 | die "Too many header lines (limit is $max_header_lines)"; | 
| 384 |  |  |  |  |  |  | } | 
| 385 |  |  |  |  |  |  | } | 
| 386 |  |  |  |  |  |  | } | 
| 387 | 20 |  |  |  |  | 86 | return @headers; | 
| 388 |  |  |  |  |  |  | } | 
| 389 |  |  |  |  |  |  |  | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | sub read_response_headers { | 
| 392 | 20 |  |  | 20 | 0 | 2382 | my($self, %opt) = @_; | 
| 393 | 20 |  |  |  |  | 36 | my $laxed = $opt{laxed}; | 
| 394 |  |  |  |  |  |  |  | 
| 395 | 20 |  |  |  |  | 50 | my($status, $eol) = my_readline($self, 'Status'); | 
| 396 | 20 | 50 |  |  |  | 49 | unless (defined $status) { | 
| 397 | 0 |  |  |  |  | 0 | die "Server closed connection without sending any data back"; | 
| 398 |  |  |  |  |  |  | } | 
| 399 |  |  |  |  |  |  |  | 
| 400 | 20 |  |  |  |  | 104 | my($peer_ver, $code, $message) = split(/\s+/, $status, 3); | 
| 401 | 20 | 100 | 66 |  |  | 199 | if (!$peer_ver || $peer_ver !~ s,^HTTP/,, || $code !~ /^[1-5]\d\d$/) { | 
|  |  |  | 66 |  |  |  |  | 
| 402 | 2 | 100 |  |  |  | 11 | 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 |  |  |  |  | 1 | ${*$self}{'http_status'} = "200"; | 
|  | 1 |  |  |  |  | 3 |  | 
| 406 | 1 |  | 50 |  |  | 3 | substr(${*$self}{'http_buf'}, 0, 0) = $status . ($eol || ""); | 
|  | 1 |  |  |  |  | 3 |  | 
| 407 | 1 | 50 |  |  |  | 3 | return 200 unless wantarray; | 
| 408 | 1 |  |  |  |  | 4 | return (200, "Assumed OK"); | 
| 409 |  |  |  |  |  |  | }; | 
| 410 |  |  |  |  |  |  |  | 
| 411 | 18 |  |  |  |  | 43 | ${*$self}{'http_peer_http_version'} = $peer_ver; | 
|  | 18 |  |  |  |  | 56 |  | 
| 412 | 18 |  |  |  |  | 39 | ${*$self}{'http_status'} = $code; | 
|  | 18 |  |  |  |  | 40 |  | 
| 413 |  |  |  |  |  |  |  | 
| 414 | 18 |  |  |  |  | 28 | my $junk_out; | 
| 415 | 18 | 100 |  |  |  | 40 | if ($laxed) { | 
| 416 | 1 |  | 50 |  |  | 4 | $junk_out = $opt{junk_out} || []; | 
| 417 |  |  |  |  |  |  | } | 
| 418 | 18 |  |  |  |  | 93 | my @headers = $self->_read_header_lines($junk_out); | 
| 419 |  |  |  |  |  |  |  | 
| 420 |  |  |  |  |  |  | # pick out headers that read_entity_body might need | 
| 421 | 17 |  |  |  |  | 39 | my @te; | 
| 422 |  |  |  |  |  |  | my $content_length; | 
| 423 | 17 |  |  |  |  | 62 | for (my $i = 0; $i < @headers; $i += 2) { | 
| 424 | 84 |  |  |  |  | 128 | my $h = lc($headers[$i]); | 
| 425 | 84 | 100 |  |  |  | 266 | if ($h eq 'transfer-encoding') { | 
|  |  | 100 |  |  |  |  |  | 
| 426 | 4 |  |  |  |  | 9 | my $te = $headers[$i+1]; | 
| 427 | 4 |  |  |  |  | 9 | $te =~ s/^\s+//; | 
| 428 | 4 |  |  |  |  | 6 | $te =~ s/\s+$//; | 
| 429 | 4 | 50 |  |  |  | 17 | push(@te, $te) if length($te); | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  | elsif ($h eq 'content-length') { | 
| 432 |  |  |  |  |  |  | # ignore bogus and overflow values | 
| 433 | 12 | 50 |  |  |  | 63 | if ($headers[$i+1] =~ /^\s*(\d{1,15})(?:\s|$)/) { | 
| 434 | 12 |  |  |  |  | 43 | $content_length = $1; | 
| 435 |  |  |  |  |  |  | } | 
| 436 |  |  |  |  |  |  | } | 
| 437 |  |  |  |  |  |  | } | 
| 438 | 17 |  |  |  |  | 50 | ${*$self}{'http_te'} = join(",", @te); | 
|  | 17 |  |  |  |  | 47 |  | 
| 439 | 17 |  |  |  |  | 25 | ${*$self}{'http_content_length'} = $content_length; | 
|  | 17 |  |  |  |  | 36 |  | 
| 440 | 17 |  |  |  |  | 23 | ${*$self}{'http_first_body'}++; | 
|  | 17 |  |  |  |  | 52 |  | 
| 441 | 17 |  |  |  |  | 52 | delete ${*$self}{'http_trailers'}; | 
|  | 17 |  |  |  |  | 41 |  | 
| 442 | 17 | 50 |  |  |  | 45 | return $code unless wantarray; | 
| 443 | 17 |  |  |  |  | 149 | return ($code, $message, @headers); | 
| 444 |  |  |  |  |  |  | } | 
| 445 |  |  |  |  |  |  |  | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | sub read_entity_body { | 
| 448 | 1153 |  |  | 1153 | 0 | 6567 | my $self = shift; | 
| 449 | 1153 |  |  |  |  | 1423 | my $buf_ref = \$_[0]; | 
| 450 | 1153 |  |  |  |  | 1405 | my $size = $_[1]; | 
| 451 | 1153 | 50 |  |  |  | 1927 | die "Offset not supported yet" if $_[2]; | 
| 452 |  |  |  |  |  |  |  | 
| 453 | 1153 |  |  |  |  | 1437 | my $chunked; | 
| 454 |  |  |  |  |  |  | my $bytes; | 
| 455 |  |  |  |  |  |  |  | 
| 456 | 1153 | 100 |  |  |  | 1297 | if (${*$self}{'http_first_body'}) { | 
|  | 1153 |  |  |  |  | 2336 |  | 
| 457 | 17 |  |  |  |  | 23 | ${*$self}{'http_first_body'} = 0; | 
|  | 17 |  |  |  |  | 34 |  | 
| 458 | 17 |  |  |  |  | 27 | delete ${*$self}{'http_chunked'}; | 
|  | 17 |  |  |  |  | 30 |  | 
| 459 | 17 |  |  |  |  | 25 | delete ${*$self}{'http_bytes'}; | 
|  | 17 |  |  |  |  | 25 |  | 
| 460 | 17 |  |  |  |  | 26 | my $method = shift(@{${*$self}{'http_request_method'}}); | 
|  | 17 |  |  |  |  | 19 |  | 
|  | 17 |  |  |  |  | 48 |  | 
| 461 | 17 |  |  |  |  | 27 | my $status = ${*$self}{'http_status'}; | 
|  | 17 |  |  |  |  | 34 |  | 
| 462 | 17 | 100 |  |  |  | 47 | 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 |  |  |  |  | 46 | elsif (my $te = ${*$self}{'http_te'}) { | 
| 467 | 3 |  |  |  |  | 14 | my @te = split(/\s*,\s*/, lc($te)); | 
| 468 | 3 | 50 |  |  |  | 11 | die "Chunked must be last Transfer-Encoding '$te'" | 
| 469 |  |  |  |  |  |  | unless pop(@te) eq "chunked"; | 
| 470 | 3 |  | 66 |  |  | 14 | pop(@te) while @te && $te[-1] eq "chunked";  # ignore repeated chunked spec | 
| 471 |  |  |  |  |  |  |  | 
| 472 | 3 |  |  |  |  | 6 | 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 |  |  |  |  | 5 | @te = reverse(@te); | 
| 501 |  |  |  |  |  |  |  | 
| 502 | 3 | 50 |  |  |  | 7 | ${*$self}{'http_te2'} = @te ? \@te : ""; | 
|  | 3 |  |  |  |  | 7 |  | 
| 503 | 3 |  |  |  |  | 7 | $chunked = -1; | 
| 504 |  |  |  |  |  |  | } | 
| 505 | 13 |  |  |  |  | 44 | elsif (defined(my $content_length = ${*$self}{'http_content_length'})) { | 
| 506 | 11 |  |  |  |  | 23 | $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 | 1136 |  |  |  |  | 1312 | $chunked = ${*$self}{'http_chunked'}; | 
|  | 1136 |  |  |  |  | 2111 |  | 
| 522 | 1136 |  |  |  |  | 1456 | $bytes   = ${*$self}{'http_bytes'}; | 
|  | 1136 |  |  |  |  | 1727 |  | 
| 523 |  |  |  |  |  |  | } | 
| 524 |  |  |  |  |  |  |  | 
| 525 | 1153 | 100 |  |  |  | 2336 | 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 |  |  |  | 52 | if ($chunked <= 0) { | 
| 532 | 12 |  |  |  |  | 18 | my $line = my_readline($self, 'Entity body'); | 
| 533 | 12 | 100 |  |  |  | 22 | if ($chunked == 0) { | 
| 534 | 9 | 50 | 33 |  |  | 41 | die "Missing newline after chunk data: '$line'" | 
| 535 |  |  |  |  |  |  | if !defined($line) || $line ne ""; | 
| 536 | 9 |  |  |  |  | 13 | $line = my_readline($self, 'Entity body'); | 
| 537 |  |  |  |  |  |  | } | 
| 538 | 12 | 50 |  |  |  | 19 | die "EOF when chunk header expected" unless defined($line); | 
| 539 | 12 |  |  |  |  | 14 | my $chunk_len = $line; | 
| 540 | 12 |  |  |  |  | 19 | $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 |  |  |  |  | 12 | ${*$self}{'http_chunked'} = $chunked; | 
|  | 12 |  |  |  |  | 20 |  | 
| 546 | 12 | 100 |  |  |  | 27 | if ($chunked == 0) { | 
| 547 | 3 |  |  |  |  | 6 | ${*$self}{'http_trailers'} = [$self->_read_header_lines]; | 
|  | 3 |  |  |  |  | 7 |  | 
| 548 | 3 |  |  |  |  | 6 | $$buf_ref = ""; | 
| 549 |  |  |  |  |  |  |  | 
| 550 | 3 |  |  |  |  | 4 | my $n = 0; | 
| 551 | 3 | 50 |  |  |  | 3 | if (my $transforms = delete ${*$self}{'http_te2'}) { | 
|  | 3 |  |  |  |  | 9 |  | 
| 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 |  |  |  |  | 5 |  | 
| 561 | 3 |  |  |  |  | 4 | ${*$self}{'http_bytes'} = 0; | 
|  | 3 |  |  |  |  | 5 |  | 
| 562 |  |  |  |  |  |  |  | 
| 563 | 3 |  |  |  |  | 7 | return $n; | 
| 564 |  |  |  |  |  |  | } | 
| 565 |  |  |  |  |  |  | } | 
| 566 |  |  |  |  |  |  |  | 
| 567 | 15 |  |  |  |  | 16 | my $n = $chunked; | 
| 568 | 15 | 50 | 33 |  |  | 41 | $n = $size if $size && $size < $n; | 
| 569 | 15 |  |  |  |  | 31 | $n = my_read($self, $$buf_ref, $n); | 
| 570 | 15 | 50 |  |  |  | 183 | return undef unless defined $n; | 
| 571 |  |  |  |  |  |  |  | 
| 572 | 15 |  |  |  |  | 18 | ${*$self}{'http_chunked'} = $chunked - $n; | 
|  | 15 |  |  |  |  | 23 |  | 
| 573 |  |  |  |  |  |  |  | 
| 574 | 15 | 50 |  |  |  | 25 | if ($n > 0) { | 
| 575 | 15 | 50 |  |  |  | 15 | if (my $transforms = ${*$self}{'http_te2'}) { | 
|  | 15 |  |  |  |  | 31 |  | 
| 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 |  |  |  |  | 24 | return $n; | 
| 584 |  |  |  |  |  |  | } | 
| 585 |  |  |  |  |  |  | elsif (defined $bytes) { | 
| 586 | 1130 | 100 |  |  |  | 1741 | unless ($bytes) { | 
| 587 | 12 |  |  |  |  | 24 | $$buf_ref = ""; | 
| 588 | 12 |  |  |  |  | 25 | return 0; | 
| 589 |  |  |  |  |  |  | } | 
| 590 | 1118 |  |  |  |  | 1359 | my $n = $bytes; | 
| 591 | 1118 | 100 | 66 |  |  | 2973 | $n = $size if $size && $size < $n; | 
| 592 | 1118 |  |  |  |  | 1807 | $n = my_read($self, $$buf_ref, $n); | 
| 593 | 1118 | 100 |  |  |  | 25775 | ${*$self}{'http_bytes'} = defined $n ? $bytes - $n : $bytes; | 
|  | 1118 |  |  |  |  | 2059 |  | 
| 594 | 1118 |  |  |  |  | 2253 | return $n; | 
| 595 |  |  |  |  |  |  | } | 
| 596 |  |  |  |  |  |  | else { | 
| 597 |  |  |  |  |  |  | # read until eof | 
| 598 | 5 |  | 50 |  |  | 9 | $size ||= 8*1024; | 
| 599 | 5 |  |  |  |  | 9 | return my_read($self, $$buf_ref, $size); | 
| 600 |  |  |  |  |  |  | } | 
| 601 |  |  |  |  |  |  | } | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | sub get_trailers { | 
| 604 | 13 |  |  | 13 | 0 | 71 | my $self = shift; | 
| 605 | 13 | 100 |  |  |  | 15 | @{${*$self}{'http_trailers'} || []}; | 
|  | 13 |  |  |  |  | 13 |  | 
|  | 13 |  |  |  |  | 71 |  | 
| 606 |  |  |  |  |  |  | } | 
| 607 |  |  |  |  |  |  |  | 
| 608 | 0 |  |  |  |  | 0 | BEGIN { | 
| 609 | 5 |  |  | 5 |  | 2171 | my $gunzip_ok; | 
| 610 | 5 |  |  |  |  | 176 | 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.21 | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | =head1 AUTHOR | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | Gisle Aas | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 665 |  |  |  |  |  |  |  | 
| 666 |  |  |  |  |  |  | This software is copyright (c) 2001-2017 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__ |