--- AnyEvent-HTTP/HTTP.pm 2013/05/17 07:19:23 1.116 +++ AnyEvent-HTTP/HTTP.pm 2015/04/07 01:18:20 1.121 @@ -48,7 +48,7 @@ use base Exporter::; -our $VERSION = '2.15'; +our $VERSION = 2.21; our @EXPORT = qw(http_get http_post http_head http_request); @@ -91,7 +91,7 @@ destroyed before the callback is called, the request will be cancelled. The callback will be called with the response body data as first argument -(or C if an error occured), and a hash-ref with response headers +(or C if an error occurred), and a hash-ref with response headers (and trailers) as second argument. All the headers in that hash are lowercased. In addition to the response @@ -159,6 +159,11 @@ Whether to recurse requests or not, e.g. on redirects, authentication and other retries and so on, and how often to do so. +Only redirects to http and https URLs are supported. While most common +redirection forms are handled entirely within this module, some require +the use of the optional L module. If it is required but missing, then +the request will fail with an error. + =item headers => hashref The request headers to use. Currently, C may provide its own @@ -244,7 +249,7 @@ =item on_prepare => $callback->($fh) In rare cases you need to "tune" the socket before it is used to -connect (for exmaple, to bind it on a given IP address). This parameter +connect (for example, to bind it on a given IP address). This parameter overrides the prepare callback passed to C and behaves exactly the same way (e.g. it has to provide a timeout). See the description for the C<$prepare_cb> argument of @@ -823,7 +828,7 @@ # the key to use in the keepalive cache my $ka_key = "$uscheme\x00$uhost\x00$uport\x00$arg{sessionid}"; - $hdr{connection} = ($persistent ? $keepalive ? "keep-alive " : "" : "close ") . "Te"; #1.1 + $hdr{connection} = ($persistent ? $keepalive ? "keep-alive, " : "" : "close, ") . "Te"; #1.1 $hdr{te} = "trailers" unless exists $hdr{te}; #1.1 my %state = (connect_guard => 1); @@ -843,10 +848,10 @@ "$method $rpath HTTP/1.1\015\012" . (join "", map "\u$_: $hdr{$_}\015\012", grep defined $hdr{$_}, keys %hdr) . "\015\012" - . (delete $arg{body}) + . $arg{body} ); - # return if error occured during push_write() + # return if error occurred during push_write() return unless %state; # reduce memory usage, save a kitten, also re-use it for the response headers. @@ -883,19 +888,42 @@ } # redirect handling - # microsoft and other shitheads don't give a shit for following standards, - # try to support some common forms of broken Location headers. - if ($hdr{location} !~ /^(?: $ | [^:\/?\#]+ : )/x) { - $hdr{location} =~ s/^\.\/+//; - - my $url = "$rscheme://$uhost:$uport"; - - unless ($hdr{location} =~ s/^\///) { - $url .= $upath; - $url =~ s/\/[^\/]*$//; + # relative uri handling forced by microsoft and other shitheads. + # we give our best and fall back to URI if available. + if (exists $hdr{location}) { + my $loc = $hdr{location}; + + if ($loc =~ m%^//%) { # // + $loc = "$rscheme:$loc"; + + } elsif ($loc eq "") { + $loc = $url; + + } elsif ($loc !~ /^(?: $ | [^:\/?\#]+ : )/x) { # anything "simple" + $loc =~ s/^\.\/+//; + + if ($loc !~ m%^[.?#]%) { + my $prefix = "$rscheme://$uhost:$uport"; + + unless ($loc =~ s/^\///) { + $prefix .= $upath; + $prefix =~ s/\/[^\/]*$//; + } + + $loc = "$prefix/$loc"; + + } elsif (eval { require URI }) { # uri + $loc = URI->new_abs ($loc, $url)->as_string; + + } else { + return _error %state, $cb, { @pseudo, Status => 599, Reason => "Cannot parse Location (URI module missing)" }; + #$hdr{Status} = 599; + #$hdr{Reason} = "Unparsable Redirect (URI module missing)"; + #$recurse = 0; + } } - $hdr{location} = "$url/$hdr{location}"; + $hdr{location} = $loc; } my $redirect; @@ -907,12 +935,13 @@ # 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. + # we go with the industry standard. 308 is defined + # by rfc7538 if ($status == 301 or $status == 302 or $status == 303) { # HTTP/1.1 is unclear on how to mutate the method $method = "GET" unless $method eq "HEAD"; $redirect = 1; - } elsif ($status == 307) { + } elsif ($status == 307 or $status == 308) { $redirect = 1; } } @@ -1246,11 +1275,11 @@ You should call this function (with a true C<$session_end>) before you save cookies to disk, and you should call this function after loading them -again. If you have a long-running program you can additonally call this +again. If you have a long-running program you can additionally call this function from time to time. A cookie jar is initially an empty hash-reference that is managed by this -module. It's format is subject to change, but currently it is like this: +module. Its format is subject to change, but currently it is as follows: The key C has to contain C<1>, otherwise the hash gets emptied. All other keys are hostnames or IP addresses pointing to @@ -1305,7 +1334,7 @@ =item $AnyEvent::HTTP::MAX_PER_HOST The maximum number of concurrent connections to the same host (identified -by the hostname). If the limit is exceeded, then the additional requests +by the hostname). If the limit is exceeded, then additional requests are queued until previous connections are closed. Both persistent and non-persistent connections are counted in this limit. @@ -1313,9 +1342,9 @@ increase it much. For comparison: the RFC's recommend 4 non-persistent or 2 persistent -connections, older browsers used 2, newers (such as firefox 3) typically -use 6, and Opera uses 8 because like, they have the fastest browser and -give a shit for everybody else on the planet. +connections, older browsers used 2, newer ones (such as firefox 3) +typically use 6, and Opera uses 8 because like, they have the fastest +browser and give a shit for everybody else on the planet. =item $AnyEvent::HTTP::PERSISTENT_TIMEOUT @@ -1394,7 +1423,7 @@ =head2 SHOWCASE -This section contaisn some more elaborate "real-world" examples or code +This section contains some more elaborate "real-world" examples or code snippets. =head2 HTTP/1.1 FILE DOWNLOAD @@ -1408,7 +1437,7 @@ on older servers. It calls the completion callback with either C, which means a -nonretryable error occured, C<0> when the download was partial and should +nonretryable error occurred, C<0> when the download was partial and should be retried, and C<1> if it was successful. use AnyEvent::HTTP;