Skip Menu |

This queue is for tickets about the SOAP-Lite CPAN distribution.

Report information
The Basics
Id: 104469
Status: new
Priority: 0/
Queue: SOAP-Lite

People
Owner: Nobody in particular
Requestors: john [...] calva.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: PATCH_HTTP_KEEPALIVE breaks connection caching.
Date: Sat, 16 May 2015 13:04:16 +0200
To: bug-SOAP-Lite [...] rt.cpan.org
From: John Hughes <john [...] calva.com>
I wrote a little client using SOAP::Lite and was supprised to see that it was making a new https call for every SOAP call. Investigation showed the problem was because PATCH_HTTP_KEEPALIVE was set. in SOAP::Transport::HTTP The "patch" is: *collect = sub { if ( defined $_[2]->header('Connection') && $_[2]->header('Connection') eq 'Keep-Alive' ) { my $data = $_[3]->(); my $next = $_[2]->header('Content-Length') && SOAP::Utils::bytelength($$data) == $_[2]->header('Content-Length') ? sub { my $str = ''; \$str; } : $_[3]; my $done = 0; $_[3] = sub { $done++ ? &$next : $data; }; } goto &$collect; }; It calls the "collector" subroutine ($_[3]) *once* to get the response data if the "Connection: Keep-Alive" header is present. But the collector subroutine in LWP::Protocol::http is: sub { my $buf = ""; #prevent use of uninitialized value in SSLeay.xs my $n; READ: { $n = $socket->read_entity_body($buf, $size); unless (defined $n) { redo READ if $!{EINTR} || $!{EAGAIN} || $!{ENOTTY}; die "read failed: $!"; } redo READ if $n == -1; } $complete++ if !$n; return \$buf; } The "$complete" flag is only set when $socket->read_entity_body returns 0, which never happens if the SOAP::Lite patch is in place. Since LWP::Protocol::http thinks the reply isn't complete it doesn't cache the connection: # keep-alive support unless ($drop_connection) { if ($cache_key) { my %connection = map { (lc($_) => 1) } split(/\s*,\s*/, ($response->header("Connection") || "")); if (($peer_http_version eq "1.1" && !$connection{close}) || $connection{"keep-alive"}) { $conn_cache->deposit($self->socket_type, $cache_key, $socket); } } } So, unintuitively, if the server returns "Connection: Keep-Alive" the connection is not cached. -- John Hughes, CalvaEDI S.A.S.