LWP::Protocol:http does not check for temporary errors during upload
am 13.08.2007 03:31:27 von jasonI had much difficulty in attempting to use 'trickle', a bandwidth
constraining utility, to limit the upload speed of flickr_upload,
which uses the Flickr::API modules, which in turn use
LWP::Protocol::http. An error response from LWP::Protocol::http was
being propogated back upward and causing the upload to abort.
I traced the problem to this segment of code in LWP/Protocol/http.pm:
if (defined($wbits) && $wbits =~ /[^\0]/) {
my $n = $socket->syswrite($$wbuf, length($$wbuf), $woffset);
unless ($n) {
die "syswrite: $!" unless defined $n;
die "syswrite: no bytes written";
}
$woffset += $n;
After the syswrite, the error response is not checked for a temporary
error like "Resource temporarily unavailable" and just fails outright.
I modified the code in my personal copy to:
- retry if the error response is "Resource temporarily unavailable"
- make smaller writes (makes for smoother rate shaping with 'trickle')
- use Time::HiRes and sleep for a short period of time between attempts
if (defined($wbits) && $wbits =~ /[^\0]/) {
my $n;
do {
$n = $socket->syswrite($$wbuf, 2048, $woffset);
} while ($! eq 'Resource temporarily unavailable' &&
sleep(0.005));
unless ($n) {
die "syswrite: $!" unless defined $n;
die "syswrite: no bytes written";
}
$woffset += $n;
That's probably not the most ideal general-purpose remedy, but it
worked great in getting it to not fail outright when run with trickle.
In any case, I thought I would point out this problem so that it could
perhaps be addressed in a future release of LWP.
Thanks!
-jrs