From: Amos Jeffries Date: Fri, 6 Jun 2014 09:38:02 +0000 (-0700) Subject: Fix regression in client read buffer X-Git-Tag: SQUID_3_5_0_1~195 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=50ae17d68e0ec2438227629f63a61bdc83910594;p=thirdparty%2Fsquid.git Fix regression in client read buffer SBuf acts like a floating 'window' of space in a MemBlob which acts a essentially like a ring-buffer. However on requests with body payload being drop-fed in very small amounts it is possible to exactly fill the MemBlob and also to shuffle the SBuf window right to the end. It is also possible if an earlier request (or the headers associated with the drip-fed body is holding the beginning of the underlying MemBlob. These events cause haveCapadity==0 so haveCapacity*2 == 0. If this happens we need to allocate a new MemBlob to get any space for future I/O. The old MemBlob will be released by whatever other SBuf was holding it locked. --- diff --git a/src/client_side.cc b/src/client_side.cc index 9c8890849b..56a00c1411 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2387,9 +2387,15 @@ ConnStateData::In::maybeMakeSpaceAvailable() debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize); return false; } - const SBuf::size_type wantCapacity = min(static_cast(Config.maxRequestBufferSize), haveCapacity*2); - buf.reserveCapacity(wantCapacity); - debugs(33, 2, "growing request buffer: available=" << buf.spaceSize() << " used=" << buf.length()); + if (haveCapacity == 0) { + // haveCapacity is based on the SBuf visible window of the MemBlob buffer, which may fill up. + // at which point bump the buffer back to default. This allocates a new MemBlob with any un-parsed bytes. + buf.reserveCapacity(CLIENT_REQ_BUF_SZ); + } else { + const SBuf::size_type wantCapacity = min(static_cast(Config.maxRequestBufferSize), haveCapacity*2); + buf.reserveCapacity(wantCapacity); + } + debugs(33, 2, "growing request buffer: available=" << buf.spaceSize() << " used=" << buf.length() << " want=" << wantCapacity); } return (buf.spaceSize() >= 2); } @@ -3276,7 +3282,8 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : log_addr = xact->tcpClient->remote; log_addr.applyMask(Config.Addrs.client_netmask); - in.buf.reserveCapacity(CLIENT_REQ_BUF_SZ); + // ensure a buffer is present for this connection + in.maybeMakeSpaceAvailable(); if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF && (transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {