Revision: 14394
Author: adrian.chadd
Date: Wed Feb 10 23:10:44 2010
Log: Begin migrating the client-side ranges handling code out of
client_side.c
and into a separate file.
It's quite possible this needs some more thought - eg the multipart handling
may not necessarily be just for ranges - but i'll worry about that later.
Untangling dependencies is more important atm.
http://code.google.com/p/lusca-cache/source/detail?r=14394
Added:
/branches/LUSCA_HEAD/src/client_side_ranges.c
/branches/LUSCA_HEAD/src/client_side_ranges.h
Modified:
/branches/LUSCA_HEAD/src/Makefile.am
/branches/LUSCA_HEAD/src/client_side.c
=======================================
--- /dev/null
+++ /branches/LUSCA_HEAD/src/client_side_ranges.c Wed Feb 10 23:10:44 2010
@@ -0,0 +1,170 @@
+#include "squid.h"
+
+#include "client_side_ranges.h"
+
+/* XXX */
+static const char *const crlf = "\r\n";
+
+
+/* put terminating boundary for multiparts */
+void
+clientPackTermBound(String boundary, MemBuf * mb)
+{
+ memBufPrintf(mb, "\r\n--%.*s--\r\n", strLen2(boundary),
strBuf2(boundary));
+ debug(33, 6) ("clientPackTermBound: buf offset: %ld\n", (long int)
mb->size);
+}
+
+/* appends a "part" HTTP header (as in a multi-part/range reply) to the
buffer */
+void
+clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec,
String boundary, MemBuf * mb)
+{
+ HttpHeader hdr;
+ Packer p;
+ assert(rep);
+ assert(spec);
+
+ /* put boundary */
+ debug(33, 5) ("clientPackRangeHdr: appending boundary: %.*s\n",
strLen2(boundary), strBuf2(boundary));
+ /* rfc2046 requires to _prepend_ boundary with <crlf>! */
+ memBufPrintf(mb, "\r\n--%.*s\r\n", strLen2(boundary),
strBuf2(boundary));
+
+ /* stuff the header with required entries and pack it */
+ httpHeaderInit(&hdr, hoReply);
+ if (httpHeaderHas(&rep->header, HDR_CONTENT_TYPE))
+ httpHeaderPutStr(&hdr, HDR_CONTENT_TYPE, httpHeaderGetStr(&rep->header,
HDR_CONTENT_TYPE));
+ httpHeaderAddContRange(&hdr, *spec, rep->content_length);
+ packerToMemInit(&p, mb);
+ httpHeaderPackInto(&hdr, &p);
+ packerClean(&p);
+ httpHeaderClean(&hdr);
+
+ /* append <crlf> (we packed a header, not a reply) */
+ memBufPrintf(mb, crlf);
+}
+
+/*
+ * extracts a "range" from *buf and appends them to mb, updating
+ * all offsets and such.
+ */
+void
+clientPackRange(clientHttpRequest * http,
+ HttpHdrRangeIter * i,
+ const char **buf,
+ size_t * size,
+ MemBuf * mb)
+{
+ const size_t copy_sz = i->debt_size <= *size ? i->debt_size : *size;
+ squid_off_t body_off = http->out.offset - i->prefix_size;
+ assert(*size > 0);
+ assert(i->spec);
+ /*
+ * intersection of "have" and "need" ranges must not be empty
+ */
+ assert(body_off < i->spec->offset + i->spec->length);
+ assert(body_off + *size > i->spec->offset);
+ /*
+ * put boundary and headers at the beginning of a range in a
+ * multi-range
+ */
+ if (http->request->range->specs.count > 1 && i->debt_size ==
i->spec->length) {
+ assert(http->entry->mem_obj);
+ clientPackRangeHdr(
+ http->entry->mem_obj->reply, /* original reply */
+ i->spec, /* current range */
+ i->boundary, /* boundary, the same for all */
+ mb
+ );
+ }
+ /*
+ * append content
+ */
+ debug(33, 3) ("clientPackRange: appending %ld bytes\n", (long int)
copy_sz);
+ memBufAppend(mb, *buf, copy_sz);
+ /*
+ * update offsets
+ */
+ *size -= copy_sz;
+ i->debt_size -= copy_sz;
+ body_off += copy_sz;
+ *buf += copy_sz;
+ http->out.offset = body_off + i->prefix_size; /* sync */
+ /*
+ * paranoid check
+ */
+ assert(i->debt_size >= 0);
+}
+
+/* returns true if there is still data available to pack more ranges
+ * increments iterator "i"
+ * used by clientPackMoreRanges */
+int
+clientCanPackMoreRanges(const clientHttpRequest * http, HttpHdrRangeIter *
i, size_t size)
+{
+ /* first update "i" if needed */
+ if (!i->debt_size) {
+ if ((i->spec = httpHdrRangeGetSpec(http->request->range, &i->pos)))
+ i->debt_size = i->spec->length;
+ }
+ assert(!i->debt_size == !i->spec); /* paranoid sync condition */
+ /* continue condition: need_more_data && have_more_data */
+ return i->spec && size > 0;
+}
+
+/* extracts "ranges" from buf and appends them to mb, updating all offsets
and such */
+/* returns true if we need more data */
+int
+clientPackMoreRanges(clientHttpRequest * http, const char *buf, size_t
size, MemBuf * mb)
+{
+ HttpHdrRangeIter *i = &http->range_iter;
+ /* offset in range specs does not count the prefix of an http msg */
+ squid_off_t body_off = http->out.offset - i->prefix_size;
+
+ /* check: reply was parsed and range iterator was initialized */
+ assert(i->prefix_size > 0);
+ /* filter out data according to range specs */
+ while (clientCanPackMoreRanges(http, i, size)) {
+ squid_off_t start; /* offset of still missing data */
+ assert(i->spec);
+ start = i->spec->offset + i->spec->length - i->debt_size;
+ debug(33, 3) ("clientPackMoreRanges: in: offset: %ld size: %ld\n",
+ (long int) body_off, (long int) size);
+ debug(33, 3) ("clientPackMoreRanges: out: start: %ld spec[%ld]:
[%ld, %ld), len: %ld debt: %ld\n",
+ (long int) start, (long int) i->pos, (long int) i->spec->offset,
(long int) (i->spec->offset + i->spec->length), (long int) i->spec->length,
(long int) i->debt_size);
+ assert(body_off <= start); /* we did not miss it */
+ /* skip up to start */
+ if (body_off + size > start) {
+ const size_t skip_size = start - body_off;
+ body_off = start;
+ size -= skip_size;
+ buf += skip_size;
+ } else {
+ /* has not reached start yet */
+ body_off += size;
+ size = 0;
+ buf = NULL;
+ }
+ /* put next chunk if any */
+ if (size) {
+ http->out.offset = body_off + i->prefix_size; /* sync */
+ clientPackRange(http, i, &buf, &size, mb);
+ body_off = http->out.offset - i->prefix_size; /* sync */
+ }
+ }
+ assert(!i->debt_size == !i->spec); /* paranoid sync condition */
+ debug(33, 3) ("clientPackMoreRanges: buf exhausted: in: offset: %ld
size: %ld need_more: %ld\n",
+ (long int) body_off, (long int) size, (long int) i->debt_size);
+ if (i->debt_size) {
+ debug(33, 3) ("clientPackMoreRanges: need more: spec[%ld]: [%ld, %ld),
len: %ld\n",
+ (long int) i->pos, (long int) i->spec->offset, (long int)
(i->spec->offset + i->spec->length), (long int) i->spec->length);
+ /* skip the data we do not need if possible */
+ if (i->debt_size == i->spec->length) /* at the start of the cur. spec
*/
+ body_off = i->spec->offset;
+ else
+ assert(body_off == i->spec->offset + i->spec->length -
i->debt_size);
+ } else if (http->request->range->specs.count > 1) {
+ /* put terminating boundary for multiparts */
+ clientPackTermBound(i->boundary, mb);
+ }
+ http->out.offset = body_off + i->prefix_size; /* sync */
+ return i->debt_size > 0;
+}
=======================================
--- /dev/null
+++ /branches/LUSCA_HEAD/src/client_side_ranges.h Wed Feb 10 23:10:44 2010
@@ -0,0 +1,11 @@
+#ifndef __CLIENT_SIDE_RANGES_H__
+#define __CLIENT_SIDE_RANGES_H__
+
+extern void clientPackTermBound(String boundary, MemBuf * mb);
+extern void clientPackRangeHdr(const HttpReply * rep, const
HttpHdrRangeSpec * spec, String boundary, MemBuf * mb);
+extern void clientPackRange(clientHttpRequest * http, HttpHdrRangeIter *
i, const char **buf, size_t * size,
+ MemBuf * mb);
+extern int clientCanPackMoreRanges(const clientHttpRequest * http,
HttpHdrRangeIter * i, size_t size);
+extern int clientPackMoreRanges(clientHttpRequest * http, const char *buf,
size_t size, MemBuf * mb);
+
+#endif
=======================================
--- /branches/LUSCA_HEAD/src/Makefile.am Wed Feb 10 08:28:07 2010
+++ /branches/LUSCA_HEAD/src/Makefile.am Wed Feb 10 23:10:44 2010
@@ -112,6 +112,7 @@
client_side_conn.c \
client_side_nat.c \
client_side_rewrite.c \
+ client_side_ranges.c \
client_side_storeurl_rewrite.c \
client_side_location_rewrite.c \
comm.c \
=======================================
--- /branches/LUSCA_HEAD/src/client_side.c Wed Feb 10 15:53:21 2010
+++ /branches/LUSCA_HEAD/src/client_side.c Wed Feb 10 23:10:44 2010
@@ -97,6 +97,7 @@
#endif
#include "client_side_request.h"
+#include "client_side_ranges.h"
#if LINGERING_CLOSE
#define comm_close comm_lingering_close
@@ -135,8 +136,6 @@
static STHCB clientSendHeaders;
static STHCB clientCacheHit;
static void clientSetKeepaliveFlag(clientHttpRequest *);
-static void clientPackRangeHdr(const HttpReply * rep, const
HttpHdrRangeSpec * spec, String boundary, MemBuf * mb);
-static void clientPackTermBound(String boundary, MemBuf * mb);
static void clientProcessExpired(clientHttpRequest *);
static void clientRefreshCheck(clientHttpRequest *);
static REFRESHCHECK clientRefreshCheckDone;
@@ -2150,169 +2149,6 @@
http->log_type = LOG_TCP_MEM_HIT;
clientSendHeaders(http, e->mem_obj->reply);
}
-
-/* put terminating boundary for multiparts */
-static void
-clientPackTermBound(String boundary, MemBuf * mb)
-{
- memBufPrintf(mb, "\r\n--%.*s--\r\n", strLen2(boundary),
strBuf2(boundary));
- debug(33, 6) ("clientPackTermBound: buf offset: %ld\n", (long int)
mb->size);
-}
-
-/* appends a "part" HTTP header (as in a multi-part/range reply) to the
buffer */
-static void
-clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec,
String boundary, MemBuf * mb)
-{
- HttpHeader hdr;
- Packer p;
- assert(rep);
- assert(spec);
-
- /* put boundary */
- debug(33, 5) ("clientPackRangeHdr: appending boundary: %.*s\n",
strLen2(boundary), strBuf2(boundary));
- /* rfc2046 requires to _prepend_ boundary with <crlf>! */
- memBufPrintf(mb, "\r\n--%.*s\r\n", strLen2(boundary),
strBuf2(boundary));
-
- /* stuff the header with required entries and pack it */
- httpHeaderInit(&hdr, hoReply);
- if (httpHeaderHas(&rep->header, HDR_CONTENT_TYPE))
- httpHeaderPutStr(&hdr, HDR_CONTENT_TYPE, httpHeaderGetStr(&rep->header,
HDR_CONTENT_TYPE));
- httpHeaderAddContRange(&hdr, *spec, rep->content_length);
- packerToMemInit(&p, mb);
- httpHeaderPackInto(&hdr, &p);
- packerClean(&p);
- httpHeaderClean(&hdr);
-
- /* append <crlf> (we packed a header, not a reply) */
- memBufPrintf(mb, crlf);
-}
-
-/*
- * extracts a "range" from *buf and appends them to mb, updating
- * all offsets and such.
- */
-static void
-clientPackRange(clientHttpRequest * http,
- HttpHdrRangeIter * i,
- const char **buf,
- size_t * size,
- MemBuf * mb)
-{
- const size_t copy_sz = i->debt_size <= *size ? i->debt_size : *size;
- squid_off_t body_off = http->out.offset - i->prefix_size;
- assert(*size > 0);
- assert(i->spec);
- /*
- * intersection of "have" and "need" ranges must not be empty
- */
- assert(body_off < i->spec->offset + i->spec->length);
- assert(body_off + *size > i->spec->offset);
- /*
- * put boundary and headers at the beginning of a range in a
- * multi-range
- */
- if (http->request->range->specs.count > 1 && i->debt_size ==
i->spec->length) {
- assert(http->entry->mem_obj);
- clientPackRangeHdr(
- http->entry->mem_obj->reply, /* original reply */
- i->spec, /* current range */
- i->boundary, /* boundary, the same for all */
- mb
- );
- }
- /*
- * append content
- */
- debug(33, 3) ("clientPackRange: appending %ld bytes\n", (long int)
copy_sz);
- memBufAppend(mb, *buf, copy_sz);
- /*
- * update offsets
- */
- *size -= copy_sz;
- i->debt_size -= copy_sz;
- body_off += copy_sz;
- *buf += copy_sz;
- http->out.offset = body_off + i->prefix_size; /* sync */
- /*
- * paranoid check
- */
- assert(i->debt_size >= 0);
-}
-
-/* returns true if there is still data available to pack more ranges
- * increments iterator "i"
- * used by clientPackMoreRanges */
-static int
-clientCanPackMoreRanges(const clientHttpRequest * http, HttpHdrRangeIter *
i, size_t size)
-{
- /* first update "i" if needed */
- if (!i->debt_size) {
- if ((i->spec = httpHdrRangeGetSpec(http->request->range, &i->pos)))
- i->debt_size = i->spec->length;
- }
- assert(!i->debt_size == !i->spec); /* paranoid sync condition */
- /* continue condition: need_more_data && have_more_data */
- return i->spec && size > 0;
-}
-
-/* extracts "ranges" from buf and appends them to mb, updating all offsets
and such */
-/* returns true if we need more data */
-static int
-clientPackMoreRanges(clientHttpRequest * http, const char *buf, size_t
size, MemBuf * mb)
-{
- HttpHdrRangeIter *i = &http->range_iter;
- /* offset in range specs does not count the prefix of an http msg */
- squid_off_t body_off = http->out.offset - i->prefix_size;
-
- /* check: reply was parsed and range iterator was initialized */
- assert(i->prefix_size > 0);
- /* filter out data according to range specs */
- while (clientCanPackMoreRanges(http, i, size)) {
- squid_off_t start; /* offset of still missing data */
- assert(i->spec);
- start = i->spec->offset + i->spec->length - i->debt_size;
- debug(33, 3) ("clientPackMoreRanges: in: offset: %ld size: %ld\n",
- (long int) body_off, (long int) size);
- debug(33, 3) ("clientPackMoreRanges: out: start: %ld spec[%ld]:
[%ld, %ld), len: %ld debt: %ld\n",
- (long int) start, (long int) i->pos, (long int) i->spec->offset,
(long int) (i->spec->offset + i->spec->length), (long int) i->spec->length,
(long int) i->debt_size);
- assert(body_off <= start); /* we did not miss it */
- /* skip up to start */
- if (body_off + size > start) {
- const size_t skip_size = start - body_off;
- body_off = start;
- size -= skip_size;
- buf += skip_size;
- } else {
- /* has not reached start yet */
- body_off += size;
- size = 0;
- buf = NULL;
- }
- /* put next chunk if any */
- if (size) {
- http->out.offset = body_off + i->prefix_size; /* sync */
- clientPackRange(http, i, &buf, &size, mb);
- body_off = http->out.offset - i->prefix_size; /* sync */
- }
- }
- assert(!i->debt_size == !i->spec); /* paranoid sync condition */
- debug(33, 3) ("clientPackMoreRanges: buf exhausted: in: offset: %ld
size: %ld need_more: %ld\n",
- (long int) body_off, (long int) size, (long int) i->debt_size);
- if (i->debt_size) {
- debug(33, 3) ("clientPackMoreRanges: need more: spec[%ld]: [%ld, %ld),
len: %ld\n",
- (long int) i->pos, (long int) i->spec->offset, (long int)
(i->spec->offset + i->spec->length), (long int) i->spec->length);
- /* skip the data we do not need if possible */
- if (i->debt_size == i->spec->length) /* at the start of the cur. spec
*/
- body_off = i->spec->offset;
- else
- assert(body_off == i->spec->offset + i->spec->length -
i->debt_size);
- } else if (http->request->range->specs.count > 1) {
- /* put terminating boundary for multiparts */
- clientPackTermBound(i->boundary, mb);
- }
- http->out.offset = body_off + i->prefix_size; /* sync */
- return i->debt_size > 0;
-}
/*
* Calculates the maximum size allowed for an HTTP response
--
You received this message because you are subscribed to the Google Groups
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/lusca-commit?hl=en.