--- AnyEvent-HTTP/HTTP.pm 2010/12/31 22:40:54 1.74 +++ AnyEvent-HTTP/HTTP.pm 2011/01/01 19:13:41 1.77 @@ -124,9 +124,23 @@ joined together with a comma (C<,>), as per the HTTP spec. If an internal error occurs, such as not being able to resolve a hostname, -then C<$data> will be C, C<< $headers->{Status} >> will be C<59x> -(usually C<599>) and the C pseudo-header will contain an error -message. +then C<$data> will be C, C<< $headers->{Status} >> will be +C<590>-C<599> and the C pseudo-header will contain an error +message. Currently the following status codes are used: + +=over 4 + +=item 595 - errors during connection etsbalishment, proxy handshake. + +=item 596 - errors during TLS negotiation, request sending and header processing. + +=item 597 - errors during body receive or processing. + +=item 598 - user aborted request in C or C. + +=item 599 - other, usually nonretryable, errors (garbled URL etc.). + +=back A typical callback might look like this: @@ -602,16 +616,16 @@ return unless $state{connect_guard}; + my $ae_error = 595; # connecting + my $connect_cb = sub { $state{fh} = shift or do { my $err = "$!"; %state = (); - return $cb->(undef, { @pseudo, Status => 599, Reason => $err }); + return $cb->(undef, { @pseudo, Status => $ae_error, Reason => $err }); }; - pop; # free memory, save a tree - return unless delete $state{connect_guard}; # get handle @@ -623,11 +637,11 @@ timeout => $timeout, on_error => sub { %state = (); - $cb->(undef, { @pseudo, Status => 599, Reason => $_[2] }); + $cb->(undef, { @pseudo, Status => $ae_error, Reason => $_[2] }); }, on_eof => sub { %state = (); - $cb->(undef, { @pseudo, Status => 599, Reason => "Unexpected end-of-file" }); + $cb->(undef, { @pseudo, Status => $ae_error, Reason => "Unexpected end-of-file" }); }, ; @@ -645,6 +659,8 @@ # handle actual, non-tunneled, request my $handle_actual_request = sub { + $ae_error = 596; # request phase + $state{handle}->starttls ("connect") if $uscheme eq "https" && !exists $state{handle}{tls}; # send request @@ -665,7 +681,7 @@ for ("$_[1]") { y/\015//d; # weed out any \015, as they show up in the weirdest of places. - /^HTTP\/([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\012]*) )? \012/igxc + /^HTTP\/0*([0-9\.]+) \s+ ([0-9]{3}) (?: \s+ ([^\012]*) )? \012/gxci or return (%state = (), $cb->(undef, { @pseudo, Status => 599, Reason => "Invalid server response" })); # 100 Continue handling @@ -710,7 +726,7 @@ my $status = $hdr{Status}; # industry standard is to redirect POST as GET for - # 301, 302 and 303, in contrast to http/1.0 and 1.1. + # 301, 302 and 303, in contrast to HTTP/1.0 and 1.1. # also, the UA should ask the user for 301 and 307 and POST, # industry standard seems to be to simply follow. # we go with the industry standard. @@ -754,6 +770,8 @@ } }; + $ae_error = 597; # body phase + my $len = $hdr{"content-length"}; if (!$redirect && $arg{on_header} && !$arg{on_header}(\%hdr)) { @@ -784,11 +802,9 @@ my $body = undef; my $on_body = $arg{on_body} || sub { $body .= shift; 1 }; - $_[0]->on_error (sub { $finish->(undef, 599 => $_[2]) }); - my $read_chunk; $read_chunk = sub { $_[1] =~ /^([0-9a-fA-F]+)/ - or $finish->(undef, 599 => "Garbled chunked transfer encoding"); + or $finish->(undef, $ae_error => "Garbled chunked transfer encoding"); my $len = hex $1; @@ -801,7 +817,7 @@ $_[0]->push_read (line => sub { length $_[1] - and return $finish->(undef, 599 => "Garbled chunked transfer encoding"); + and return $finish->(undef, $ae_error => "Garbled chunked transfer encoding"); $_[0]->push_read (line => $read_chunk); }); }); @@ -814,7 +830,7 @@ y/\015//d; # weed out any \015, as they show up in the weirdest of places. my $hdr = parse_hdr - or return $finish->(undef, 599 => "Garbled response trailers"); + or return $finish->(undef, $ae_error => "Garbled response trailers"); %hdr = (%hdr, %$hdr); } @@ -828,8 +844,6 @@ $_[0]->push_read (line => $read_chunk); } elsif ($arg{on_body}) { - $_[0]->on_error (sub { $finish->(undef, 599 => $_[2]) }); - if ($len) { $_[0]->on_read (sub { $len -= length $_[0]{rbuf}; @@ -853,7 +867,6 @@ $_[0]->on_eof (undef); if ($len) { - $_[0]->on_error (sub { $finish->(undef, 599 => $_[2]) }); $_[0]->on_read (sub { $finish->((substr delete $_[0]{rbuf}, 0, $len, ""), undef, undef, 1) if $len <= length $_[0]{rbuf}; @@ -862,7 +875,7 @@ $_[0]->on_error (sub { ($! == Errno::EPIPE || !$!) ? $finish->(delete $_[0]{rbuf}) - : $finish->(undef, 599 => $_[2]); + : $finish->(undef, $ae_error => $_[2]); }); $_[0]->on_read (sub { }); }