Subject: | message_file_thresh plus basic auth = disaster |
When a request is large enough to trigger message_file_thresh spooling
off to file, a closure is placed in the request's content accessor.
This closure closes over a filehandle to the serialized request, which
has at that point been reset to the beginning using seek()
However, when Basic Auth is in use, the initial request will send some
portion of the data before being interrupted with a 401, and then LWP
clones the request to re-send with credentials. This subsequent
request, while cloned, contains the same closure with the same
filehandle. The result is that only a portion of the data (what remains
from the file position) is sent on the second request. This will lead
to a short read on the server, and likely leave it blocking waiting for
data that will never arrive.
I solved this with a subclass of HTTP::Request that stores the req_fh
and calls seek on it when clone is called, like this:
package RPC::XML::Client::Request;
use base 'HTTP::Request';
sub clone {
my $self = shift;
if (exists $self->{_req_fh}) {
seek $self->{_req_fh}, 0, 0;
}
$self->SUPER::clone(@_);
}
Of course, this class is used in the constructor in place of
HTTP::Request, and I stuck the filehandle directly into the object's
hash as a matter of convenience.