From: robertc <> Date: Sun, 10 Aug 2003 09:59:19 +0000 (+0000) Subject: Summary: Fix range offsets when the full object is retrieved. X-Git-Tag: SQUID_3_0_PRE3~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2512d159a021d79b49c4ce9ecb5b78ef12cc8ac1;p=thirdparty%2Fsquid.git Summary: Fix range offsets when the full object is retrieved. Keywords: * Extend StoreIOBuffer to provide Range details. * Extend ClientSocketContext::lengthToSend to be offset aware and adjust throughout. * ClientSocketContext::packRange - tidy up the calling interface, make private, and skip unwanted data at the beginning as well as the end of ranges. --- diff --git a/src/StoreIOBuffer.h b/src/StoreIOBuffer.h index 04d49aaf4c..863b29d6eb 100644 --- a/src/StoreIOBuffer.h +++ b/src/StoreIOBuffer.h @@ -1,6 +1,6 @@ /* - * $Id: StoreIOBuffer.h,v 1.3 2003/02/21 22:50:06 robertc Exp $ + * $Id: StoreIOBuffer.h,v 1.4 2003/08/10 03:59:19 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -29,10 +29,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * + * Copyright (c) 2003, Robert Collins */ -#ifndef SQUID_STOREIORESULT_H -#define SQUID_STOREIORESULT_H +#ifndef SQUID_STOREIOBUFFER_H +#define SQUID_STOREIOBUFFER_H + +/* TODO: move this and the range() method into a .cci */ +#include "Range.h" class StoreIOBuffer { @@ -46,6 +50,11 @@ public: flags.error = 0; } + Range range() const + { + return Range(offset, offset + length); + } + struct { @@ -59,4 +68,4 @@ int error: char *data; }; -#endif /* SQUID_STOREIORESULT_H */ +#endif /* SQUID_STOREIOBUFFER_H */ diff --git a/src/client_side.cc b/src/client_side.cc index 1818d70333..9a99d7fda5 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.652 2003/08/04 22:14:41 robertc Exp $ + * $Id: client_side.cc,v 1.653 2003/08/10 03:59:19 robertc Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -753,8 +753,10 @@ ClientSocketContext::startOfOutput() const } size_t -ClientSocketContext::lengthToSend(size_t maximum) +ClientSocketContext::lengthToSend(Range const &available) { + size_t maximum = available.size(); + if (!http->request->range) return maximum; @@ -765,6 +767,10 @@ ClientSocketContext::lengthToSend(size_t maximum) assert (http->range_iter.debt() > 0); + /* TODO this + the last line could be a range intersection calculation */ + if ((ssize_t)available.start < http->range_iter.currentSpec()->offset) + return 0; + return XMIN(http->range_iter.debt(), (ssize_t)maximum); } @@ -803,7 +809,7 @@ ClientSocketContext::sendBody(HttpReply * rep, StoreIOBuffer bodyData) assert(rep == NULL); if (!multipartRangeRequest()) { - size_t length = lengthToSend(bodyData.length); + size_t length = lengthToSend(bodyData.range()); noteSentBodyBytes (length); comm_write(fd(), bodyData.data, length, clientWriteBodyComplete, this); @@ -812,11 +818,13 @@ ClientSocketContext::sendBody(HttpReply * rep, StoreIOBuffer bodyData) MemBuf mb; memBufDefInit(&mb); - char const *t = bodyData.data; - packRange(&t, bodyData.length, &mb); - /* write */ - comm_old_write_mbuf(fd(), mb, clientWriteComplete, this); - return; + packRange(bodyData, &mb); + + if (mb.size) + /* write */ + comm_old_write_mbuf(fd(), mb, clientWriteComplete, this); + else + writeComplete(fd(), NULL, 0, COMM_OK); } /* put terminating boundary for multiparts */ @@ -865,56 +873,58 @@ clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec, String * all offsets and such. */ void -ClientSocketContext::packRange(const char **buf, - size_t size, - MemBuf * mb) +ClientSocketContext::packRange(StoreIOBuffer const &source, MemBuf * mb) { HttpHdrRangeIter * i = &http->range_iter; - size_t available = size; + Range available (source.range()); + char const *buf (source.data); - while (i->currentSpec() && available) { + while (i->currentSpec() && available.size()) { const size_t copy_sz = lengthToSend(available); - /* - * intersection of "have" and "need" ranges must not be empty - */ - assert(http->out.offset < i->currentSpec()->offset + i->currentSpec()->length); - assert(http->out.offset + available > (size_t)i->currentSpec()->offset); - /* - * put boundary and headers at the beginning of a range in a - * multi-range - */ + if (copy_sz) { + /* + * intersection of "have" and "need" ranges must not be empty + */ + assert(http->out.offset < i->currentSpec()->offset + i->currentSpec()->length); + assert(http->out.offset + available.size() > (size_t)i->currentSpec()->offset); - if (http->multipartRangeRequest() && i->debt() == i->currentSpec()->length) { - assert(http->memObject()); - clientPackRangeHdr( - http->memObject()->getReply(), /* original reply */ - i->currentSpec(), /* current range */ - i->boundary, /* boundary, the same for all */ - mb); - } + /* + * put boundary and headers at the beginning of a range in a + * multi-range + */ - /* - * append content - */ - debug(33, 3) ("clientPackRange: appending %ld bytes\n", (long int) copy_sz); + if (http->multipartRangeRequest() && i->debt() == i->currentSpec()->length) { + assert(http->memObject()); + clientPackRangeHdr( + http->memObject()->getReply(), /* original reply */ + i->currentSpec(), /* current range */ + i->boundary, /* boundary, the same for all */ + mb); + } - noteSentBodyBytes (copy_sz); + /* + * append content + */ + debug(33, 3) ("clientPackRange: appending %ld bytes\n", (long int) copy_sz); - memBufAppend(mb, *buf, copy_sz); + noteSentBodyBytes (copy_sz); - /* - * update offsets - */ - available -= copy_sz; + memBufAppend(mb, buf, copy_sz); + + /* + * update offsets + */ + available.start += copy_sz; + + buf += copy_sz; - //body_off += copy_sz; - *buf += copy_sz; + } /* * paranoid check */ - assert(available >= 0 && i->debt() >= 0 || i->debt() == -1); + assert(available.size() >= 0 && i->debt() >= 0 || i->debt() == -1); if (!canPackMoreRanges()) { debug(33, 3) ("clientPackRange: Returning because !canPackMoreRanges.\n"); @@ -932,12 +942,18 @@ ClientSocketContext::packRange(const char **buf, size_t skip = next - http->out.offset; - if (available <= skip) + /* adjust for not to be transmitted bytes */ + http->out.offset = next; + + if (available.size() <= skip) return; - available -= skip; + available.start += skip; - *buf += skip; + buf += skip; + + if (copy_sz == 0) + return; } } @@ -1125,6 +1141,8 @@ ClientSocketContext::buildRangeHeader(HttpReply * rep) /* Content-Length is not required in multipart responses * but it is always nice to have one */ actual_clen = http->mRangeCLen(); + /* http->out needs to start where we want data at */ + http->out.offset = http->range_iter.currentSpec()->offset; } /* replace Content-Length header */ @@ -1164,15 +1182,12 @@ ClientSocketContext::sendStartOfMessage(HttpReply * rep, StoreIOBuffer bodyData) if (bodyData.data && bodyData.length) { if (!multipartRangeRequest()) { - size_t length = lengthToSend(bodyData.length); + size_t length = lengthToSend(bodyData.range()); noteSentBodyBytes (length); memBufAppend(&mb, bodyData.data, length); } else { - char const *t = bodyData.data; - packRange(&t, - bodyData.length, - &mb); + packRange(bodyData, &mb); } } @@ -1372,13 +1387,6 @@ ClientSocketContext::getNextRangeOffset() const return start; } -#if 0 - - } else if (http->request->range->specs.count > 1) { - /* put terminating boundary for multiparts */ - clientPackTermBound(i->boundary, mb); -#endif - } return http->out.offset; diff --git a/src/client_side.h b/src/client_side.h index a502e44144..0b17235a4a 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -1,6 +1,6 @@ /* - * $Id: client_side.h,v 1.6 2003/08/04 22:14:41 robertc Exp $ + * $Id: client_side.h,v 1.7 2003/08/10 03:59:19 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -43,6 +43,10 @@ class ClientHttpRequest; class clientStreamNode; +template + +class Range; + class ClientSocketContext : public RefCountable { @@ -96,7 +100,7 @@ int parsed_ok: clientStream_status_t socketState(); void sendBody(HttpReply * rep, StoreIOBuffer bodyData); void sendStartOfMessage(HttpReply * rep, StoreIOBuffer bodyData); - size_t lengthToSend(size_t maximum); + size_t lengthToSend(Range const &available); void noteSentBodyBytes(size_t); void buildRangeHeader(HttpReply * rep); int fd() const; @@ -106,14 +110,12 @@ int parsed_ok: void removeFromConnectionList(RefCount conn); void deferRecipientForLater(clientStreamNode * node, HttpReply * rep, StoreIOBuffer recievedData); bool multipartRangeRequest() const; - void packRange(const char **buf, - size_t size, - MemBuf * mb); void registerWithConn(); private: CBDATA_CLASS(ClientSocketContext); void prepareReply(HttpReply * rep); + void packRange(StoreIOBuffer const &, MemBuf * mb); void deRegisterWithConn(); bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */ bool connRegistered_;