--------------------- PatchSet 6023 Date: 2003/11/06 22:28:45 Author: dwsquid Branch: icap-2_5 Tag: (none) Log: more fixes to buildRespModHeader(). The recently committed version did not detect the end of the request in some cases and also did not detect when the request contains a body or not. Now we have to parse the HTTP reply to get the status and content lenght (ugh). Also fixed a problem with ICAP 204 replies and ICAP connection reuse. Members: src/icap_respmod.c:1.1.2.17->1.1.2.18 Index: squid/src/icap_respmod.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_respmod.c,v retrieving revision 1.1.2.17 retrieving revision 1.1.2.18 diff -u -r1.1.2.17 -r1.1.2.18 --- squid/src/icap_respmod.c 6 Nov 2003 18:18:53 -0000 1.1.2.17 +++ squid/src/icap_respmod.c 6 Nov 2003 22:28:45 -0000 1.1.2.18 @@ -1,5 +1,5 @@ /* - * $Id: icap_respmod.c,v 1.1.2.17 2003/11/06 18:18:53 dwsquid Exp $ + * $Id: icap_respmod.c,v 1.1.2.18 2003/11/06 22:28:45 dwsquid Exp $ * * DEBUG: section 81 Internet Content Adaptation Protocol (ICAP) Client * AUTHOR: Geetha Manjunath, Hewlett Packard Company @@ -76,20 +76,35 @@ char *client_addr; int o2; int o3; - int hlen = 0; + int hlen; + int consumed; + int bs; icap_service *service; + HttpReply *r; if (memBufIsNull(&icap->respmod.req_hdr_copy)) memBufDefInit(&icap->respmod.req_hdr_copy); - hlen = headersEnd(buf, len); - if (0 == hlen) { - /* didn't get end of HTTP response headers yet */ - memBufAppend(&icap->respmod.req_hdr_copy, buf, len); + memBufAppend(&icap->respmod.req_hdr_copy, buf, len); + hlen = headersEnd(icap->respmod.req_hdr_copy.buf, + icap->respmod.req_hdr_copy.size); + debug(81, 3) ("buildRespModHeader: headersEnd = %d\n", hlen); + if (0 == hlen) return 0; - } else { - memBufAppend(&icap->respmod.req_hdr_copy, buf, hlen); - } + + /* + * calc how many bytes from this 'buf' went towards the + * reply header. + */ + consumed = hlen - (icap->respmod.req_hdr_copy.size - len); + debug(81, 3) ("buildRespModHeader: consumed = %d\n", consumed); + + /* + * now, truncate our req_hdr_copy at the header end. + * this 'if' statement might be unncessary? + */ + if (hlen < icap->respmod.req_hdr_copy.size) + icap->respmod.req_hdr_copy.size = hlen; /* Copy request header */ memBufDefInit(&mb_hdr); @@ -102,21 +117,20 @@ icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size); o3 = mb_hdr.size; - len -= hlen; service = icap->current_service; assert(service); client_addr = inet_ntoa(icap->request->client_addr); - /* What if the buf contains only header info */ - if ((len > 0 || icap->respmod.entry->mem_obj->reply->content_length > 0) || !theEnd) + r = httpReplyCreate(); + httpReplyParse(r, icap->respmod.req_hdr_copy.buf, + icap->respmod.req_hdr_copy.size); + bs = httpReplyBodySize(icap->request->method, r); + httpReplyDestroy(r); + if (bs) getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr); else -#ifdef ICAP_CHUNKED getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr); -#else - getICAPRespModString(mb, 0, o2, -1, service->uri, client_addr); -#endif if (Config.icapcfg.preview_enable) if (icap->preview_size >= 0) memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size); @@ -127,7 +141,7 @@ memBufClean(&mb_hdr); icap->flags.keep_alive = 1; - return hlen; + return consumed; } @@ -289,7 +303,7 @@ } commSetTimeout(icap->icap_fd, -1, NULL, NULL); -#if 0 +#if 1 debug(81, 5) ("icapSendRespMod: FD %d writing {%s}\n", icap->icap_fd, mb.buf); #endif icap->flags.write_pending = 1; @@ -590,7 +604,7 @@ storeLockObject(entry); icap->http_flags = http_flags; memBufDefInit(&icap->respmod.buffer); - memBufInit(&icap->chunk_buf, SQUID_TCP_SO_RCVBUF, SQUID_TCP_SO_RCVBUF); + memBufDefInit(&icap->chunk_buf); icap->current_service = service; icap->preview_size = service->preview; @@ -649,10 +663,18 @@ debug(81, 5) ("icapPconnTransferDone: keep_alive not set, ret 0\n"); return 0; } +#if 0 + /* + * Disabling this because it breaks for large responses that dont + * fit entirely into the resp_copy MemBuf. If we return 1 here, + * the ICAP state is freed and any further data coming from the + * client side gets lost. + */ if (icap->flags.no_content) { debug(81, 5) ("icapPconnTransferDone: no content, ret 1\n"); return 1; } +#endif if (icapHttpReplyHdrState(icap) != 2) { debug(81, 5) ("icapPconnTransferDone: didn't see end of HTTP hdrs, ret 0\n"); return 0;