ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-HTTP/HTTP.pm
(Generate patch)

Comparing AnyEvent-HTTP/HTTP.pm (file contents):
Revision 1.119 by root, Sun Jun 8 23:33:28 2014 UTC vs.
Revision 1.139 by root, Fri Aug 5 20:48:14 2022 UTC

46use AnyEvent::Util (); 46use AnyEvent::Util ();
47use AnyEvent::Handle (); 47use AnyEvent::Handle ();
48 48
49use base Exporter::; 49use base Exporter::;
50 50
51our $VERSION = 2.2; 51our $VERSION = 2.25;
52 52
53our @EXPORT = qw(http_get http_post http_head http_request); 53our @EXPORT = qw(http_get http_post http_head http_request);
54 54
55our $USERAGENT = "Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)"; 55our $USERAGENT = "Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)";
56our $MAX_RECURSE = 10; 56our $MAX_RECURSE = 10;
195C<$scheme> must be either missing or must be C<http> for HTTP. 195C<$scheme> must be either missing or must be C<http> for HTTP.
196 196
197If not specified, then the default proxy is used (see 197If not specified, then the default proxy is used (see
198C<AnyEvent::HTTP::set_proxy>). 198C<AnyEvent::HTTP::set_proxy>).
199 199
200Currently, if your proxy requires authorization, you have to specify an
201appropriate "Proxy-Authorization" header in every request.
202
203Note that this module will prefer an existing persistent connection,
204even if that connection was made using another proxy. If you need to
205ensure that a new connection is made in this case, you can either force
206C<persistent> to false or e.g. use the proxy address in your C<sessionid>.
207
200=item body => $string 208=item body => $string
201 209
202The request body, usually empty. Will be sent as-is (future versions of 210The request body, usually empty. Will be sent as-is (future versions of
203this module might offer more options). 211this module might offer more options).
204 212
236The default for this option is C<low>, which could be interpreted as "give 244The default for this option is C<low>, which could be interpreted as "give
237me the page, no matter what". 245me the page, no matter what".
238 246
239See also the C<sessionid> parameter. 247See also the C<sessionid> parameter.
240 248
241=item session => $string 249=item sessionid => $string
242 250
243The module might reuse connections to the same host internally. Sometimes 251The module might reuse connections to the same host internally (regardless
244(e.g. when using TLS), you do not want to reuse connections from other 252of other settings, such as C<tcp_connect> or C<proxy>). Sometimes (e.g.
253when using TLS or a specfic proxy), you do not want to reuse connections
245sessions. This can be achieved by setting this parameter to some unique 254from other sessions. This can be achieved by setting this parameter to
246ID (such as the address of an object storing your state data, or the TLS 255some unique ID (such as the address of an object storing your state data
247context) - only connections using the same unique ID will be reused. 256or the TLS context, or the proxy IP) - only connections using the same
257unique ID will be reused.
248 258
249=item on_prepare => $callback->($fh) 259=item on_prepare => $callback->($fh)
250 260
251In rare cases you need to "tune" the socket before it is used to 261In rare cases you need to "tune" the socket before it is used to
252connect (for example, to bind it on a given IP address). This parameter 262connect (for example, to bind it on a given IP address). This parameter
260In even rarer cases you want total control over how AnyEvent::HTTP 270In even rarer cases you want total control over how AnyEvent::HTTP
261establishes connections. Normally it uses L<AnyEvent::Socket::tcp_connect> 271establishes connections. Normally it uses L<AnyEvent::Socket::tcp_connect>
262to do this, but you can provide your own C<tcp_connect> function - 272to do this, but you can provide your own C<tcp_connect> function -
263obviously, it has to follow the same calling conventions, except that it 273obviously, it has to follow the same calling conventions, except that it
264may always return a connection guard object. 274may always return a connection guard object.
275
276The connections made by this hook will be treated as equivalent to
277connections made the built-in way, specifically, they will be put into
278and taken from the persistent connection cache. If your C<$tcp_connect>
279function is incompatible with this kind of re-use, consider switching off
280C<persistent> connections and/or providing a C<sessionid> identifier.
265 281
266There are probably lots of weird uses for this function, starting from 282There are probably lots of weird uses for this function, starting from
267tracing the hosts C<http_request> actually tries to connect, to (inexact 283tracing the hosts C<http_request> actually tries to connect, to (inexact
268but fast) host => IP address caching or even socks protocol support. 284but fast) host => IP address caching or even socks protocol support.
269 285
339=item persistent => $boolean 355=item persistent => $boolean
340 356
341Try to create/reuse a persistent connection. When this flag is set 357Try to create/reuse a persistent connection. When this flag is set
342(default: true for idempotent requests, false for all others), then 358(default: true for idempotent requests, false for all others), then
343C<http_request> tries to re-use an existing (previously-created) 359C<http_request> tries to re-use an existing (previously-created)
344persistent connection to the host and, failing that, tries to create a new 360persistent connection to same host (i.e. identical URL scheme, hostname,
345one. 361port and sessionid) and, failing that, tries to create a new one.
346 362
347Requests failing in certain ways will be automatically retried once, which 363Requests failing in certain ways will be automatically retried once, which
348is dangerous for non-idempotent requests, which is why it defaults to off 364is dangerous for non-idempotent requests, which is why it defaults to off
349for them. The reason for this is because the bozos who designed HTTP/1.1 365for them. The reason for this is because the bozos who designed HTTP/1.1
350made it impossible to distinguish between a fatal error and a normal 366made it impossible to distinguish between a fatal error and a normal
351connection timeout, so you never know whether there was a problem with 367connection timeout, so you never know whether there was a problem with
352your request or not. 368your request or not.
353 369
354When reusing an existent connection, many parameters (such as TLS context) 370When reusing an existent connection, many parameters (such as TLS context)
355will be ignored. See the C<session> parameter for a workaround. 371will be ignored. See the C<sessionid> parameter for a workaround.
356 372
357=item keepalive => $boolean 373=item keepalive => $boolean
358 374
359Only used when C<persistent> is also true. This parameter decides whether 375Only used when C<persistent> is also true. This parameter decides whether
360C<http_request> tries to handshake a HTTP/1.0-style keep-alive connection 376C<http_request> tries to handshake a HTTP/1.0-style keep-alive connection
451 467
452# expire cookies 468# expire cookies
453sub cookie_jar_expire($;$) { 469sub cookie_jar_expire($;$) {
454 my ($jar, $session_end) = @_; 470 my ($jar, $session_end) = @_;
455 471
456 %$jar = () if $jar->{version} != 1; 472 %$jar = () if $jar->{version} != 2;
457 473
458 my $anow = AE::now; 474 my $anow = AE::now;
459 475
460 while (my ($chost, $paths) = each %$jar) { 476 while (my ($chost, $paths) = each %$jar) {
461 next unless ref $paths; 477 next unless ref $paths;
481 497
482# extract cookies from jar 498# extract cookies from jar
483sub cookie_jar_extract($$$$) { 499sub cookie_jar_extract($$$$) {
484 my ($jar, $scheme, $host, $path) = @_; 500 my ($jar, $scheme, $host, $path) = @_;
485 501
486 %$jar = () if $jar->{version} != 1; 502 %$jar = () if $jar->{version} != 2;
503
504 $host = AnyEvent::Util::idn_to_ascii $host
505 if $host =~ /[^\x00-\x7f]/;
487 506
488 my @cookies; 507 my @cookies;
489 508
490 while (my ($chost, $paths) = each %$jar) { 509 while (my ($chost, $paths) = each %$jar) {
491 next unless ref $paths; 510 next unless ref $paths;
492 511
493 if ($chost =~ /^\./) { 512 # exact match or suffix including . match
494 next unless $chost eq substr $host, -length $chost; 513 $chost eq $host or ".$chost" eq substr $host, -1 - length $chost
495 } elsif ($chost =~ /\./) {
496 next unless $chost eq $host;
497 } else {
498 next; 514 or next;
499 }
500 515
501 while (my ($cpath, $cookies) = each %$paths) { 516 while (my ($cpath, $cookies) = each %$paths) {
502 next unless $cpath eq substr $path, 0, length $cpath; 517 next unless $cpath eq substr $path, 0, length $cpath;
503 518
504 while (my ($cookie, $kv) = each %$cookies) { 519 while (my ($cookie, $kv) = each %$cookies) {
525} 540}
526 541
527# parse set_cookie header into jar 542# parse set_cookie header into jar
528sub cookie_jar_set_cookie($$$$) { 543sub cookie_jar_set_cookie($$$$) {
529 my ($jar, $set_cookie, $host, $date) = @_; 544 my ($jar, $set_cookie, $host, $date) = @_;
545
546 %$jar = () if $jar->{version} != 2;
530 547
531 my $anow = int AE::now; 548 my $anow = int AE::now;
532 my $snow; # server-now 549 my $snow; # server-now
533 550
534 for ($set_cookie) { 551 for ($set_cookie) {
580 597
581 my $cdom; 598 my $cdom;
582 my $cpath = (delete $kv{path}) || "/"; 599 my $cpath = (delete $kv{path}) || "/";
583 600
584 if (exists $kv{domain}) { 601 if (exists $kv{domain}) {
585 $cdom = delete $kv{domain}; 602 $cdom = $kv{domain};
586 603
587 $cdom =~ s/^\.?/./; # make sure it starts with a "." 604 $cdom =~ s/^\.?/./; # make sure it starts with a "."
588 605
589 next if $cdom =~ /\.$/; 606 next if $cdom =~ /\.$/;
590 607
591 # this is not rfc-like and not netscape-like. go figure. 608 # this is not rfc-like and not netscape-like. go figure.
592 my $ndots = $cdom =~ y/.//; 609 my $ndots = $cdom =~ y/.//;
593 next if $ndots < ($cdom =~ /\.[^.][^.]\.[^.][^.]$/ ? 3 : 2); 610 next if $ndots < ($cdom =~ /\.[^.][^.]\.[^.][^.]$/ ? 3 : 2);
611
612 $cdom = substr $cdom, 1; # remove initial .
594 } else { 613 } else {
595 $cdom = $host; 614 $cdom = $host;
596 } 615 }
597 616
598 # store it 617 # store it
599 $jar->{version} = 1; 618 $jar->{version} = 2;
600 $jar->{lc $cdom}{$cpath}{$name} = \%kv; 619 $jar->{lc $cdom}{$cpath}{$name} = \%kv;
601 620
602 redo if /\G\s*,/gc; 621 redo if /\G\s*,/gc;
603 } 622 }
604} 623}
697} 716}
698 717
699our %IDEMPOTENT = ( 718our %IDEMPOTENT = (
700 DELETE => 1, 719 DELETE => 1,
701 GET => 1, 720 GET => 1,
721 QUERY => 1,
702 HEAD => 1, 722 HEAD => 1,
703 OPTIONS => 1, 723 OPTIONS => 1,
704 PUT => 1, 724 PUT => 1,
705 TRACE => 1, 725 TRACE => 1,
706 726
718 MKCOL => 1, 738 MKCOL => 1,
719 MKREDIRECTREF => 1, 739 MKREDIRECTREF => 1,
720 MKWORKSPACE => 1, 740 MKWORKSPACE => 1,
721 MOVE => 1, 741 MOVE => 1,
722 ORDERPATCH => 1, 742 ORDERPATCH => 1,
743 PRI => 1,
723 PROPFIND => 1, 744 PROPFIND => 1,
724 PROPPATCH => 1, 745 PROPPATCH => 1,
725 REBIND => 1, 746 REBIND => 1,
726 REPORT => 1, 747 REPORT => 1,
727 SEARCH => 1, 748 SEARCH => 1,
770 791
771 my $uport = $uscheme eq "http" ? 80 792 my $uport = $uscheme eq "http" ? 80
772 : $uscheme eq "https" ? 443 793 : $uscheme eq "https" ? 443
773 : return $cb->(undef, { @pseudo, Status => 599, Reason => "Only http and https URL schemes supported" }); 794 : return $cb->(undef, { @pseudo, Status => 599, Reason => "Only http and https URL schemes supported" });
774 795
775 $uauthority =~ /^(?: .*\@ )? ([^\@:]+) (?: : (\d+) )?$/x 796 $uauthority =~ /^(?: .*\@ )? ([^\@]+?) (?: : (\d+) )?$/x
776 or return $cb->(undef, { @pseudo, Status => 599, Reason => "Unparsable URL" }); 797 or return $cb->(undef, { @pseudo, Status => 599, Reason => "Unparsable URL" });
777 798
778 my $uhost = lc $1; 799 my $uhost = lc $1;
779 $uport = $2 if defined $2; 800 $uport = $2 if defined $2;
780 801
846 # send request 867 # send request
847 $hdl->push_write ( 868 $hdl->push_write (
848 "$method $rpath HTTP/1.1\015\012" 869 "$method $rpath HTTP/1.1\015\012"
849 . (join "", map "\u$_: $hdr{$_}\015\012", grep defined $hdr{$_}, keys %hdr) 870 . (join "", map "\u$_: $hdr{$_}\015\012", grep defined $hdr{$_}, keys %hdr)
850 . "\015\012" 871 . "\015\012"
851 . (delete $arg{body}) 872 . $arg{body}
852 ); 873 );
853 874
854 # return if error occurred during push_write() 875 # return if error occurred during push_write()
855 return unless %state; 876 return unless %state;
856 877
892 # we give our best and fall back to URI if available. 913 # we give our best and fall back to URI if available.
893 if (exists $hdr{location}) { 914 if (exists $hdr{location}) {
894 my $loc = $hdr{location}; 915 my $loc = $hdr{location};
895 916
896 if ($loc =~ m%^//%) { # // 917 if ($loc =~ m%^//%) { # //
897 $loc = "$rscheme:$loc"; 918 $loc = "$uscheme:$loc";
898 919
899 } elsif ($loc eq "") { 920 } elsif ($loc eq "") {
900 $loc = $url; 921 $loc = $url;
901 922
902 } elsif ($loc !~ /^(?: $ | [^:\/?\#]+ : )/x) { # anything "simple" 923 } elsif ($loc !~ /^(?: $ | [^:\/?\#]+ : )/x) { # anything "simple"
903 $loc =~ s/^\.\/+//; 924 $loc =~ s/^\.\/+//;
904 925
905 if ($loc !~ m%^[.?#]%) { 926 if ($loc !~ m%^[.?#]%) {
906 my $prefix = "$rscheme://$uhost:$uport"; 927 my $prefix = "$uscheme://$uauthority";
907 928
908 unless ($loc =~ s/^\///) { 929 unless ($loc =~ s/^\///) {
909 $prefix .= $upath; 930 $prefix .= $upath;
910 $prefix =~ s/\/[^\/]*$//; 931 $prefix =~ s/\/[^\/]*$//;
911 } 932 }
934 # industry standard is to redirect POST as GET for 955 # industry standard is to redirect POST as GET for
935 # 301, 302 and 303, in contrast to HTTP/1.0 and 1.1. 956 # 301, 302 and 303, in contrast to HTTP/1.0 and 1.1.
936 # also, the UA should ask the user for 301 and 307 and POST, 957 # also, the UA should ask the user for 301 and 307 and POST,
937 # industry standard seems to be to simply follow. 958 # industry standard seems to be to simply follow.
938 # we go with the industry standard. 308 is defined 959 # we go with the industry standard. 308 is defined
939 # by rfc7238 960 # by rfc7538
940 if ($status == 301 or $status == 302 or $status == 303) { 961 if ($status == 301 or $status == 302 or $status == 303) {
962 $redirect = 1;
941 # HTTP/1.1 is unclear on how to mutate the method 963 # HTTP/1.1 is unclear on how to mutate the method
942 $method = "GET" unless $method eq "HEAD"; 964 unless ($method eq "HEAD") {
943 $redirect = 1; 965 $method = "GET";
966 delete $arg{body};
967 }
944 } elsif ($status == 307 or $status == 308) { 968 } elsif ($status == 307 or $status == 308) {
945 $redirect = 1; 969 $redirect = 1;
946 } 970 }
947 } 971 }
948 972
1025 $finish->(delete $state{handle}); 1049 $finish->(delete $state{handle});
1026 1050
1027 } elsif ($chunked) { 1051 } elsif ($chunked) {
1028 my $cl = 0; 1052 my $cl = 0;
1029 my $body = ""; 1053 my $body = "";
1030 my $on_body = $arg{on_body} || sub { $body .= shift; 1 }; 1054 my $on_body = (!$redirect && $arg{on_body}) || sub { $body .= shift; 1 };
1031 1055
1032 $state{read_chunk} = sub { 1056 $state{read_chunk} = sub {
1033 $_[1] =~ /^([0-9a-fA-F]+)/ 1057 $_[1] =~ /^([0-9a-fA-F]+)/
1034 or return $finish->(undef, $ae_error => "Garbled chunked transfer encoding"); 1058 or return $finish->(undef, $ae_error => "Garbled chunked transfer encoding");
1035 1059
1068 } 1092 }
1069 }; 1093 };
1070 1094
1071 $_[0]->push_read (line => $state{read_chunk}); 1095 $_[0]->push_read (line => $state{read_chunk});
1072 1096
1073 } elsif ($arg{on_body}) { 1097 } elsif (!$redirect && $arg{on_body}) {
1074 if (defined $len) { 1098 if (defined $len) {
1075 $_[0]->on_read (sub { 1099 $_[0]->on_read (sub {
1076 $len -= length $_[0]{rbuf}; 1100 $len -= length $_[0]{rbuf};
1077 1101
1078 $arg{on_body}(delete $_[0]{rbuf}, \%hdr) 1102 $arg{on_body}(delete $_[0]{rbuf}, \%hdr)
1117 _destroy_state %state; 1141 _destroy_state %state;
1118 1142
1119 %state = (); 1143 %state = ();
1120 $state{recurse} = 1144 $state{recurse} =
1121 http_request ( 1145 http_request (
1122 $method => $url, 1146 $method => $url,
1123 %arg, 1147 %arg,
1124 recurse => $recurse - 1, 1148 recurse => $recurse - 1,
1125 keepalive => 0, 1149 persistent => 0,
1126 sub { 1150 sub {
1127 %state = (); 1151 %state = ();
1128 &$cb 1152 &$cb
1129 } 1153 }
1130 ); 1154 );
1176 1200
1177 # now handle proxy-CONNECT method 1201 # now handle proxy-CONNECT method
1178 if ($proxy && $uscheme eq "https") { 1202 if ($proxy && $uscheme eq "https") {
1179 # oh dear, we have to wrap it into a connect request 1203 # oh dear, we have to wrap it into a connect request
1180 1204
1205 my $auth = exists $hdr{"proxy-authorization"}
1206 ? "proxy-authorization: " . (delete $hdr{"proxy-authorization"}) . "\015\012"
1207 : "";
1208
1181 # maybe re-use $uauthority with patched port? 1209 # maybe re-use $uauthority with patched port?
1182 $state{handle}->push_write ("CONNECT $uhost:$uport HTTP/1.0\015\012\015\012"); 1210 $state{handle}->push_write ("CONNECT $uhost:$uport HTTP/1.0\015\012$auth\015\012");
1183 $state{handle}->push_read (line => $qr_nlnl, sub { 1211 $state{handle}->push_read (line => $qr_nlnl, sub {
1184 $_[1] =~ /^HTTP\/([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\015\012]*) )?/ix 1212 $_[1] =~ /^HTTP\/([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\015\012]*) )?/ix
1185 or return _error %state, $cb, { @pseudo, Status => 599, Reason => "Invalid proxy connect response ($_[1])" }; 1213 or return _error %state, $cb, { @pseudo, Status => 599, Reason => "Invalid proxy connect response ($_[1])" };
1186 1214
1187 if ($2 == 200) { 1215 if ($2 == 200) {
1190 } else { 1218 } else {
1191 _error %state, $cb, { @pseudo, Status => $2, Reason => $3 }; 1219 _error %state, $cb, { @pseudo, Status => $2, Reason => $3 };
1192 } 1220 }
1193 }); 1221 });
1194 } else { 1222 } else {
1223 delete $hdr{"proxy-authorization"} unless $proxy;
1224
1195 $handle_actual_request->(); 1225 $handle_actual_request->();
1196 } 1226 }
1197 }; 1227 };
1198 1228
1199 _get_slot $uhost, sub { 1229 _get_slot $uhost, sub {
1205 # on a keepalive request (in theory, this should be a separate config option). 1235 # on a keepalive request (in theory, this should be a separate config option).
1206 if ($persistent && $KA_CACHE{$ka_key}) { 1236 if ($persistent && $KA_CACHE{$ka_key}) {
1207 $was_persistent = 1; 1237 $was_persistent = 1;
1208 1238
1209 $state{handle} = ka_fetch $ka_key; 1239 $state{handle} = ka_fetch $ka_key;
1210 $state{handle}->destroyed 1240# $state{handle}->destroyed
1211 and die "AnyEvent::HTTP: unexpectedly got a destructed handle (1), please report.";#d# 1241# and die "AnyEvent::HTTP: unexpectedly got a destructed handle (1), please report.";#d#
1212 $prepare_handle->(); 1242 $prepare_handle->();
1213 $state{handle}->destroyed 1243# $state{handle}->destroyed
1214 and die "AnyEvent::HTTP: unexpectedly got a destructed handle (2), please report.";#d# 1244# and die "AnyEvent::HTTP: unexpectedly got a destructed handle (2), please report.";#d#
1245 $rpath = $upath;
1215 $handle_actual_request->(); 1246 $handle_actual_request->();
1216 1247
1217 } else { 1248 } else {
1218 my $tcp_connect = $arg{tcp_connect} 1249 my $tcp_connect = $arg{tcp_connect}
1219 || do { require AnyEvent::Socket; \&AnyEvent::Socket::tcp_connect }; 1250 || do { require AnyEvent::Socket; \&AnyEvent::Socket::tcp_connect };
1277save cookies to disk, and you should call this function after loading them 1308save cookies to disk, and you should call this function after loading them
1278again. If you have a long-running program you can additionally call this 1309again. If you have a long-running program you can additionally call this
1279function from time to time. 1310function from time to time.
1280 1311
1281A cookie jar is initially an empty hash-reference that is managed by this 1312A cookie jar is initially an empty hash-reference that is managed by this
1282module. It's format is subject to change, but currently it is like this: 1313module. Its format is subject to change, but currently it is as follows:
1283 1314
1284The key C<version> has to contain C<1>, otherwise the hash gets 1315The key C<version> has to contain C<2>, otherwise the hash gets
1285emptied. All other keys are hostnames or IP addresses pointing to 1316cleared. All other keys are hostnames or IP addresses pointing to
1286hash-references. The key for these inner hash references is the 1317hash-references. The key for these inner hash references is the
1287server path for which this cookie is meant, and the values are again 1318server path for which this cookie is meant, and the values are again
1288hash-references. Each key of those hash-references is a cookie name, and 1319hash-references. Each key of those hash-references is a cookie name, and
1289the value, you guessed it, is another hash-reference, this time with the 1320the value, you guessed it, is another hash-reference, this time with the
1290key-value pairs from the cookie, except for C<expires> and C<max-age>, 1321key-value pairs from the cookie, except for C<expires> and C<max-age>,
1294 1325
1295Here is an example of a cookie jar with a single cookie, so you have a 1326Here is an example of a cookie jar with a single cookie, so you have a
1296chance of understanding the above paragraph: 1327chance of understanding the above paragraph:
1297 1328
1298 { 1329 {
1299 version => 1, 1330 version => 2,
1300 "10.0.0.1" => { 1331 "10.0.0.1" => {
1301 "/" => { 1332 "/" => {
1302 "mythweb_id" => { 1333 "mythweb_id" => {
1303 _expires => 1293917923, 1334 _expires => 1293917923,
1304 value => "ooRung9dThee3ooyXooM1Ohm", 1335 value => "ooRung9dThee3ooyXooM1Ohm",
1332C<Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)>). 1363C<Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)>).
1333 1364
1334=item $AnyEvent::HTTP::MAX_PER_HOST 1365=item $AnyEvent::HTTP::MAX_PER_HOST
1335 1366
1336The maximum number of concurrent connections to the same host (identified 1367The maximum number of concurrent connections to the same host (identified
1337by the hostname). If the limit is exceeded, then the additional requests 1368by the hostname). If the limit is exceeded, then additional requests
1338are queued until previous connections are closed. Both persistent and 1369are queued until previous connections are closed. Both persistent and
1339non-persistent connections are counted in this limit. 1370non-persistent connections are counted in this limit.
1340 1371
1341The default value for this is C<4>, and it is highly advisable to not 1372The default value for this is C<4>, and it is highly advisable to not
1342increase it much. 1373increase it much.
1449 or die "$file: $!"; 1480 or die "$file: $!";
1450 1481
1451 my %hdr; 1482 my %hdr;
1452 my $ofs = 0; 1483 my $ofs = 0;
1453 1484
1454 warn stat $fh;
1455 warn -s _;
1456 if (stat $fh and -s _) { 1485 if (stat $fh and -s _) {
1457 $ofs = -s _; 1486 $ofs = -s _;
1458 warn "-s is ", $ofs; 1487 warn "-s is ", $ofs;
1459 $hdr{"if-unmodified-since"} = AnyEvent::HTTP::format_date +(stat _)[9]; 1488 $hdr{"if-unmodified-since"} = AnyEvent::HTTP::format_date +(stat _)[9];
1460 $hdr{"range"} = "bytes=$ofs-"; 1489 $hdr{"range"} = "bytes=$ofs-";
1488 my (undef, $hdr) = @_; 1517 my (undef, $hdr) = @_;
1489 1518
1490 my $status = $hdr->{Status}; 1519 my $status = $hdr->{Status};
1491 1520
1492 if (my $time = AnyEvent::HTTP::parse_date $hdr->{"last-modified"}) { 1521 if (my $time = AnyEvent::HTTP::parse_date $hdr->{"last-modified"}) {
1493 utime $fh, $time, $time; 1522 utime $time, $time, $fh;
1494 } 1523 }
1495 1524
1496 if ($status == 200 || $status == 206 || $status == 416) { 1525 if ($status == 200 || $status == 206 || $status == 416) {
1497 # download ok || resume ok || file already fully downloaded 1526 # download ok || resume ok || file already fully downloaded
1498 $cb->(1, $hdr); 1527 $cb->(1, $hdr);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines