… | |
… | |
15 | This module is an L<AnyEvent> user, you need to make sure that you use and |
15 | This module is an L<AnyEvent> user, you need to make sure that you use and |
16 | run a supported event loop. |
16 | run a supported event loop. |
17 | |
17 | |
18 | This module implements a simple, stateless and non-blocking HTTP |
18 | This module implements a simple, stateless and non-blocking HTTP |
19 | client. It supports GET, POST and other request methods, cookies and more, |
19 | client. It supports GET, POST and other request methods, cookies and more, |
20 | all on a very low level. It can follow redirects supports proxies and |
20 | all on a very low level. It can follow redirects, supports proxies, and |
21 | automatically limits the number of connections to the values specified in |
21 | automatically limits the number of connections to the values specified in |
22 | the RFC. |
22 | the RFC. |
23 | |
23 | |
24 | It should generally be a "good client" that is enough for most HTTP |
24 | It should generally be a "good client" that is enough for most HTTP |
25 | tasks. Simple tasks should be simple, but complex tasks should still be |
25 | tasks. Simple tasks should be simple, but complex tasks should still be |
… | |
… | |
46 | use AnyEvent::Util (); |
46 | use AnyEvent::Util (); |
47 | use AnyEvent::Handle (); |
47 | use AnyEvent::Handle (); |
48 | |
48 | |
49 | use base Exporter::; |
49 | use base Exporter::; |
50 | |
50 | |
51 | our $VERSION = '2.0'; |
51 | our $VERSION = '2.02'; |
52 | |
52 | |
53 | our @EXPORT = qw(http_get http_post http_head http_request); |
53 | our @EXPORT = qw(http_get http_post http_head http_request); |
54 | |
54 | |
55 | our $USERAGENT = "Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)"; |
55 | our $USERAGENT = "Mozilla/5.0 (compatible; U; AnyEvent-HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)"; |
56 | our $MAX_RECURSE = 10; |
56 | our $MAX_RECURSE = 10; |
… | |
… | |
546 | # quoted |
546 | # quoted |
547 | $value = $3; |
547 | $value = $3; |
548 | $value =~ s/\\(.)/$1/gs; |
548 | $value =~ s/\\(.)/$1/gs; |
549 | } |
549 | } |
550 | |
550 | |
551 | push @kv, lc $name, $value; |
551 | push @kv, @kv ? lc $name : $name, $value; |
552 | |
552 | |
553 | last unless /\G\s*;/gc; |
553 | last unless /\G\s*;/gc; |
554 | } |
554 | } |
555 | |
555 | |
556 | last unless @kv; |
556 | last unless @kv; |
… | |
… | |
1325 | # initialise proxy from environment |
1325 | # initialise proxy from environment |
1326 | eval { |
1326 | eval { |
1327 | set_proxy $ENV{http_proxy}; |
1327 | set_proxy $ENV{http_proxy}; |
1328 | }; |
1328 | }; |
1329 | |
1329 | |
|
|
1330 | =head2 SHOWCASE |
|
|
1331 | |
|
|
1332 | This section contaisn some more elaborate "real-world" examples or code |
|
|
1333 | snippets. |
|
|
1334 | |
|
|
1335 | =head2 HTTP/1.1 FILE DOWNLOAD |
|
|
1336 | |
|
|
1337 | Downloading files with HTTP can be quite tricky, especially when something |
|
|
1338 | goes wrong and you want tor esume. |
|
|
1339 | |
|
|
1340 | Here is a function that initiates and resumes a download. It uses the |
|
|
1341 | last modified time to check for file content changes, and works with many |
|
|
1342 | HTTP/1.0 servers as well, and usually falls back to a complete re-download |
|
|
1343 | on older servers. |
|
|
1344 | |
|
|
1345 | It calls the completion callback with either C<undef>, which means a |
|
|
1346 | nonretryable error occured, C<0> when the download was partial and should |
|
|
1347 | be retried, and C<1> if it was successful. |
|
|
1348 | |
|
|
1349 | use AnyEvent::HTTP; |
|
|
1350 | |
|
|
1351 | sub download($$$) { |
|
|
1352 | my ($url, $file, $cb) = @_; |
|
|
1353 | |
|
|
1354 | open my $fh, "+<", $file |
|
|
1355 | or die "$file: $!"; |
|
|
1356 | |
|
|
1357 | my %hdr; |
|
|
1358 | my $ofs = 0; |
|
|
1359 | |
|
|
1360 | warn stat $fh; |
|
|
1361 | warn -s _; |
|
|
1362 | if (stat $fh and -s _) { |
|
|
1363 | $ofs = -s _; |
|
|
1364 | warn "-s is ", $ofs;#d# |
|
|
1365 | $hdr{"if-unmodified-since"} = AnyEvent::HTTP::format_date +(stat _)[9]; |
|
|
1366 | $hdr{"range"} = "bytes=$ofs-"; |
|
|
1367 | } |
|
|
1368 | |
|
|
1369 | http_get $url, |
|
|
1370 | headers => \%hdr, |
|
|
1371 | on_header => sub { |
|
|
1372 | my ($hdr) = @_; |
|
|
1373 | |
|
|
1374 | if ($hdr->{Status} == 200 && $ofs) { |
|
|
1375 | # resume failed |
|
|
1376 | truncate $fh, $ofs = 0; |
|
|
1377 | } |
|
|
1378 | |
|
|
1379 | sysseek $fh, $ofs, 0; |
|
|
1380 | |
|
|
1381 | 1 |
|
|
1382 | }, |
|
|
1383 | on_body => sub { |
|
|
1384 | my ($data, $hdr) = @_; |
|
|
1385 | |
|
|
1386 | if ($hdr->{Status} =~ /^2/) { |
|
|
1387 | length $data == syswrite $fh, $data |
|
|
1388 | or return; # abort on write errors |
|
|
1389 | } |
|
|
1390 | |
|
|
1391 | 1 |
|
|
1392 | }, |
|
|
1393 | sub { |
|
|
1394 | my (undef, $hdr) = @_; |
|
|
1395 | |
|
|
1396 | my $status = $hdr->{Status}; |
|
|
1397 | |
|
|
1398 | if (my $time = AnyEvent::HTTP::parse_date $hdr->{"last-modified"}) { |
|
|
1399 | utime $fh, $time, $time; |
|
|
1400 | } |
|
|
1401 | |
|
|
1402 | if ($status == 200 || $status == 206 || $status == 416) { |
|
|
1403 | # download ok || resume ok || file already fully downloaded |
|
|
1404 | $cb->(1, $hdr); |
|
|
1405 | |
|
|
1406 | } elsif ($status == 412) { |
|
|
1407 | # file has changed while resuming, delete and retry |
|
|
1408 | unlink $file; |
|
|
1409 | $cb->(0, $hdr); |
|
|
1410 | |
|
|
1411 | } elsif ($status == 500 or $status == 503 or $status =~ /^59/) { |
|
|
1412 | # retry later |
|
|
1413 | $cb->(0, $hdr); |
|
|
1414 | |
|
|
1415 | } else { |
|
|
1416 | $cb->(undef, $hdr); |
|
|
1417 | } |
|
|
1418 | } |
|
|
1419 | ; |
|
|
1420 | } |
|
|
1421 | |
|
|
1422 | download "http://server/somelargefile", "/tmp/somelargefile", sub { |
|
|
1423 | if ($_[0]) { |
|
|
1424 | print "OK!\n"; |
|
|
1425 | } elsif (defined $_[0]) { |
|
|
1426 | print "please retry later\n"; |
|
|
1427 | } else { |
|
|
1428 | print "ERROR\n"; |
|
|
1429 | } |
|
|
1430 | }; |
|
|
1431 | |
1330 | =head2 SOCKS PROXIES |
1432 | =head3 SOCKS PROXIES |
1331 | |
1433 | |
1332 | Socks proxies are not directly supported by AnyEvent::HTTP. You can |
1434 | Socks proxies are not directly supported by AnyEvent::HTTP. You can |
1333 | compile your perl to support socks, or use an external program such as |
1435 | compile your perl to support socks, or use an external program such as |
1334 | F<socksify> (dante) or F<tsocks> to make your program use a socks proxy |
1436 | F<socksify> (dante) or F<tsocks> to make your program use a socks proxy |
1335 | transparently. |
1437 | transparently. |