--------------------- PatchSet 5997 Date: 2003/10/29 16:29:58 Author: dwsquid Branch: icap-2_5 Tag: (none) Log: Move icapReadChunkSize() and icapReadChunkedBody() from icap_respmod.c to icap_common.c, and rename them to icapParseChunkSize() and icapParseChunkedBody() since they dont actually do any read()ing. This move is in anticipation of using them for reading request bodies in REQMOD replies. Members: src/icap_common.c:1.1.2.16->1.1.2.17 src/icap_respmod.c:1.1.2.10->1.1.2.11 src/protos.h:1.41.6.13.2.12->1.41.6.13.2.13 Index: squid/src/icap_common.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_common.c,v retrieving revision 1.1.2.16 retrieving revision 1.1.2.17 diff -u -r1.1.2.16 -r1.1.2.17 --- squid/src/icap_common.c 27 Oct 2003 17:33:37 -0000 1.1.2.16 +++ squid/src/icap_common.c 29 Oct 2003 16:29:58 -0000 1.1.2.17 @@ -1,5 +1,5 @@ /* - * $Id: icap_common.c,v 1.1.2.16 2003/10/27 17:33:37 dwsquid Exp $ + * $Id: icap_common.c,v 1.1.2.17 2003/10/29 16:29:58 dwsquid Exp $ * * DEBUG: section 81 Internet Content Adaptation Protocol (ICAP) Client * AUTHOR: Geetha Manjunath, Hewlett Packard Company @@ -445,3 +445,135 @@ else icap->flags.keep_alive = 1; } + +/* + * icapParseChunkSize + * + * Returns the offset where the next chunk starts + * return parameter chunk_size; + */ +static int +icapParseChunkSize(const char *buf, int len, int *chunk_size) +{ + int chunkSize = 0; + char c; + size_t start; + size_t end; + size_t nextStart = 0; + do { + start = nextStart; + if (len <= start) { + /* + * end of buffer, so far no lines or only empty lines, + * wait for more data. read chunk size with next buffer. + */ + *chunk_size = 0; + return nextStart; + } + end = start + icapLineLength(buf + start, len - start); + nextStart = end; + if (end <= start) { + /* + * no line found, need more code here, now we are in + * deep trouble, buffer stops with half a chunk size + * line. For now stop here. + */ + *chunk_size = -2; + return nextStart; + } + while (start < end) { + if (NULL == strchr(w_space, buf[start])) + break; + start++; + } + while (start < end) { + if (NULL == strchr(w_space, buf[end - 1])) + break; + end--; + } + /* + * if now end <= start we got an empty line. The previous + * chunk data should stop with a CRLF. In case that the + * other end does not follow the specs and sends no CRLF + * or too many empty lines, just continue till we have a + * non-empty line. + */ + } while (end <= start); + + /* Non-empty line: Parse the chunk size */ + while (start < end) { + c = buf[start++]; + if (c >= 'a' && c <= 'f') { + chunkSize = chunkSize * 16 + c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + chunkSize = chunkSize * 16 + c - 'A' + 10; + } else if (c >= '0' && c <= '9') { + chunkSize = chunkSize * 16 + c - '0'; + } else { + if (!(c == ';' || c == ' ' || c == '\t')) { + /*Syntax error: Chunksize expected. */ + *chunk_size = -2; /* we are done */ + return nextStart; + } + /* Next comes a chunk extension */ + break; + } + } + /* + * if we read a zero chunk, we reached the end. Mark this for + * icapPconnTransferDone + */ + *chunk_size = (chunkSize > 0) ? chunkSize : -2; + return nextStart; +} + +/* + * icapParseChunkedBody + * + * De-chunk an HTTP entity received from the ICAP server. + * The 'store' function pointer is storeAppend() or memBufAppend(). + */ +void +icapParseChunkedBody(IcapStateData * icap, int len, const char *buf, STRCB * store, void *store_data) +{ + int bufOffset = 0; + + if (icap->chunk_size == -2) { + debug(81, 3) ("zero end chunk reached\n"); + return; + } + debug(81, 3) ("%s:%d: chunk_size=%d\n", __FILE__, __LINE__, + icap->chunk_size); + if (icap->chunk_size < 0) { + store(store_data, buf, len); + return; + } + debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__, + bufOffset, len); + while (bufOffset < len) { + debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__, + bufOffset, len); + if (icap->chunk_size == 0) { + bufOffset += icapParseChunkSize(buf + bufOffset, + len - bufOffset, &icap->chunk_size); + debug(81, 3) ("got chunksize %d, new offset %d\n", + icap->chunk_size, bufOffset); + if (icap->chunk_size == -2) { + debug(81, 3) ("zero end chunk reached\n"); + return; + } + } + debug(81, 3) ("%s:%d: X\n", __FILE__, __LINE__); + if (icap->chunk_size > 0) { + if (icap->chunk_size >= len - bufOffset) { + store(store_data, buf + bufOffset, len - bufOffset); + icap->chunk_size -= len - bufOffset; + bufOffset = len; + } else { + store(store_data, buf + bufOffset, icap->chunk_size); + bufOffset += icap->chunk_size; + icap->chunk_size = 0; + } + } + } +} Index: squid/src/icap_respmod.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_respmod.c,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -u -r1.1.2.10 -r1.1.2.11 --- squid/src/icap_respmod.c 29 Oct 2003 16:18:07 -0000 1.1.2.10 +++ squid/src/icap_respmod.c 29 Oct 2003 16:29:58 -0000 1.1.2.11 @@ -1,5 +1,5 @@ /* - * $Id: icap_respmod.c,v 1.1.2.10 2003/10/29 16:18:07 dwsquid Exp $ + * $Id: icap_respmod.c,v 1.1.2.11 2003/10/29 16:29:58 dwsquid Exp $ * * DEBUG: section 81 Internet Content Adaptation Protocol (ICAP) Client * AUTHOR: Geetha Manjunath, Hewlett Packard Company @@ -603,78 +603,6 @@ } static int -icapReadChunkSize(void *data, const char *buf, int len) -{ - IcapStateData *icap = data; - int chunkSize = 0; - char c; - size_t start; - size_t end; - size_t nextStart = 0; - do { - start = nextStart; - if (len <= start) { - /* end of buffer, so far no lines or only empty lines, - * wait for more data */ - icap->chunk_size = 0; /* read chunk size with next buffer */ - return nextStart; - } - end = start + icapLineLength(buf + start, len - start); - nextStart = end; - if (end <= start) { - /* no line found, need more code here, now we are in - * deep trouble, buffer stops with */ - /* half a chunk size line. For now stop here. */ - icap->chunk_size = -2; /* we are done */ - - return nextStart; - } - while (start < end) { - if (NULL == strchr(w_space, buf[start])) - break; - start++; - } - while (start < end) { - if (NULL == strchr(w_space, buf[end - 1])) - break; - end--; - } - /* if now end <= start we got an empty line */ - /* The previous chunk data should stop with a CRLF. In case */ - /* that the other end does not follow the specs and sends no */ - /* CRLF or too many empty lines, just continue till we have */ - /* a non-empty line. */ - } while (end <= start); - - /* Non-empty line: Parse the chunk size */ - while (start < end) { - c = buf[start++]; - if (c >= 'a' && c <= 'f') { - chunkSize = chunkSize * 16 + c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - chunkSize = chunkSize * 16 + c - 'A' + 10; - } else if (c >= '0' && c <= '9') { - chunkSize = chunkSize * 16 + c - '0'; - } else { - if (!(c == ';' || c == ' ' || c == '\t')) { - /*Syntax error: Chunksize expected. */ - icap->chunk_size = -2; /* we are done */ - - return nextStart; - } - /* Next comes a chunk extension */ - break; - } - } - /* - * if we read a zero chunk, we reached the end. Mark this for - * icapPconnTransferDone - */ - icap->chunk_size = (chunkSize > 0) ? chunkSize : -2; - return nextStart; -} - -static int icapHttpReplyHdrState(IcapStateData * icap) { assert(icap); @@ -683,69 +611,6 @@ return icap->httpState->reply_hdr_state; } -/* - * XXX I hate it that this function calls storeAppend() - */ -static int -icapReadChunkedBody(void *data, int len, const char *buf) -{ - IcapStateData *icap = data; - StoreEntry *entry = icap->respmod.entry; - int bufOffset; - - assert(2 == icapHttpReplyHdrState(icap)); - if (icap->chunk_size == -2) { - debug(81, 3) ("zero end chunk reached\n"); - len = 0; /* don't add anything else */ - return 0; - } - debug(81, 3) ("%s:%d: chunk_size=%d\n", __FILE__, __LINE__, icap->chunk_size); - if (icap->chunk_size < 0) { - storeAppend(entry, buf, len); - return 0; - } - /* read data which is transfered in chunked encoding */ - /* set bufOffset to beginning of body data */ - /* If header was already written to store, we can read from beginning */ - if (entry->mem_obj && entry->mem_obj->inmem_hi > 0) - bufOffset = 0; - else - bufOffset = headersEnd(buf, len); - debug(81, 3) ("%s:%d: bufOffset=%d\n", __FILE__, __LINE__, bufOffset); - - /* Store the header if we didn't do so yet */ - if (bufOffset > 0) { - debug(81, 3) ("%s:%d: calling storeAppend\n", __FILE__, __LINE__); - storeAppend(entry, buf, bufOffset); - } - debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__, bufOffset, len); - while (bufOffset < len) { - debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__, bufOffset, len); - if (icap->chunk_size == 0) { - bufOffset += icapReadChunkSize(icap, buf + bufOffset, len - bufOffset); - debug(81, 3) ("got chunksize %d, new offset %d\n", icap->chunk_size, bufOffset); - if (icap->chunk_size == -2) { - debug(81, 3) ("zero end chunk reached\n"); - return 1; /* break from httpReadReply */ - } - } - debug(81, 3) ("%s:%d: X\n", __FILE__, __LINE__); - if (icap->chunk_size > 0) { - if (icap->chunk_size >= len - bufOffset) { - storeAppend(entry, buf + bufOffset, len - bufOffset); - icap->chunk_size -= len - bufOffset; - bufOffset = len; - } else { - storeAppend(entry, buf + bufOffset, icap->chunk_size); - bufOffset += icap->chunk_size; - icap->chunk_size = 0; - } - } - } - return 0; -} - - void icapProcessHttpReplyHeader(IcapStateData * icap, const char *buf, int size) { @@ -925,7 +790,7 @@ storeAppend(entry, buf, len); } else if (2 == icapHttpReplyHdrState(icap)) { if (len) - icapReadChunkedBody(icap, len, chunkstart); + icapParseChunkedBody(icap, len, chunkstart, storeAppend, entry); } icapReadReply3(icap); return 0; Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.41.6.13.2.12 retrieving revision 1.41.6.13.2.13 diff -u -r1.41.6.13.2.12 -r1.41.6.13.2.13 --- squid/src/protos.h 17 Oct 2003 15:13:21 -0000 1.41.6.13.2.12 +++ squid/src/protos.h 29 Oct 2003 16:29:58 -0000 1.41.6.13.2.13 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.41.6.13.2.12 2003/10/17 15:13:21 dwsquid Exp $ + * $Id: protos.h,v 1.41.6.13.2.13 2003/10/29 16:29:58 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1366,6 +1366,7 @@ int icapFindHeader(const char *, const char *, const char **, const char **); int icapParseKeepAlive(const IcapStateData *, const char *, const char *); void icapSetKeepAlive(IcapStateData * icap, const char *hdrs); +void icapParseChunkedBody(IcapStateData *, int, const char *, STRCB *, void *); /*