Search squid archive

ICAP breaks HTTP responses with 1 octet bodies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




I'm having some problems with Squid's ICAP client breaking on RESPMOD when handling responses with a body exactly 1 octet long.

- The browser makes a request to Squid
- Squid makes a request to the web server and receives back a response with a "Content-Length: 1" header and a 1 octet body. - The response gets sent to the ICAP server, which replies with a "204 No Modifications". - Squid sends the response on to the browser, with the "Content-Length: 1" header intact, but doesn't send a body. The browser sits there indefinitely waiting for the body to appear.

As far as I can tell, the ICAP client successfully copies the body from the virgin response to the adapted response.

The problem appears to be with ServerStateData::handleMoreAdaptedBodyAvailable() - The API for StoreEntry::bytesWanted() seems to be that it will return 0 if it wants no data, or up to aRange.end-1 if more data is wanted. This means that if aRange.end == 1, which is the case when we only have 1 octet of data, it is always going to look like it can't accept any more data.

The fact that it can't accept a single octet is actually noted in ServerStateData::handleMoreAdaptedBodyAvailable() in Server.cc:
  // XXX: bytesWanted API does not allow us to write just one byte!

I've resolved this problem by changing the following lines in ServerStateData::handleMoreAdaptedBodyAvailable(): const size_t bytesWanted = entry->bytesWanted(Range<size_t>(0, contentSize));
  const size_t spaceAvailable = bytesWanted >  0 ? (bytesWanted + 1) : 0;

To:
const size_t spaceAvailable = entry->bytesWanted(Range<size_t>(0, contentSize+1));

(Patch attached)

However, I'm not sure if this is a correct fix - what effect does adding 1 to the contentSize given to bytesWanted() actually have? And is this supposed to be handled elsewhere?




--

 - Steve Hill
   Technical Director
   Opendium Limited     http://www.opendium.com

Direct contacts:
   Instant messager: xmpp:steve@xxxxxxxxxxxx
   Email:            steve@xxxxxxxxxxxx
   Phone:            sip:steve@xxxxxxxxxxxx

Sales / enquiries contacts:
   Email:            sales@xxxxxxxxxxxx
   Phone:            +44-844-9791439 / sip:sales@xxxxxxxxxxxx

Support contacts:
   Email:            support@xxxxxxxxxxxx
   Phone:            +44-844-4844916 / sip:support@xxxxxxxxxxxx
Index: src/Server.cc
===================================================================
--- src/Server.cc       (revision 115)
+++ src/Server.cc       (working copy)
@@ -723,8 +723,7 @@
 
     // XXX: entry->bytesWanted returns contentSize-1 if entry can accept data.
     // We have to add 1 to avoid suspending forever.
-    const size_t bytesWanted = entry->bytesWanted(Range<size_t>(0, contentSize));
-    const size_t spaceAvailable = bytesWanted >  0 ? (bytesWanted + 1) : 0;
+    const size_t spaceAvailable = entry->bytesWanted(Range<size_t>(0, contentSize+1));
 
     if (spaceAvailable < contentSize ) {
         // No or partial body data consuming
@@ -734,8 +733,7 @@
         entry->deferProducer(call);
     }
 
-    // XXX: bytesWanted API does not allow us to write just one byte!
-    if (!spaceAvailable && contentSize > 1)  {
+    if (!spaceAvailable && contentSize > 0)  {
         debugs(11, 5, HERE << "NOT storing " << contentSize << " bytes of adapted " <<
                "response body at offset " << adaptedBodySource->consumedSize());
         return;

[Index of Archives]     [Linux Audio Users]     [Samba]     [Big List of Linux Books]     [Linux USB]     [Yosemite News]

  Powered by Linux