Hi,
I've submitted this patch to D.Wessels but had no news, so i guess i'll just send it to the mailing-list :)
What it does:
. fix: case insensitive ICAP headers . fix: wrong size in REQMOD encapsulated headers . feature: client/server 204 negociation . fix: don't send ieof chunk if null-body (RESPMOD) . fix: 100 Continue bugs . fix: 204 No modification bugs
I'd be glad to hear comments or suggestions
Best regards,
/olivier
Index: acconfig.h =================================================================== RCS file: /cvsroot/squid/squid/Attic/acconfig.h,v retrieving revision 1.13.2.3.6.1 diff -u -r1.13.2.3.6.1 acconfig.h --- acconfig.h 4 Apr 2003 16:53:51 -0000 1.13.2.3.6.1 +++ acconfig.h 15 Jun 2004 11:31:19 -0000 @@ -91,7 +91,7 @@ /* * ICAP - Internet Content Adaptation Protocol */ -#undef HS_FEAT_ICAP +#define HS_FEAT_ICAP /* Index: src/icap_opt.c =================================================================== RCS file: /cvsroot/squid/squid/src/Attic/icap_opt.c,v retrieving revision 1.1.2.11 diff -u -r1.1.2.11 icap_opt.c --- src/icap_opt.c 13 May 2004 16:26:19 -0000 1.1.2.11 +++ src/icap_opt.c 15 Jun 2004 11:31:30 -0000 @@ -364,22 +364,22 @@ /* extract information */ - if (!strncmp("Allow", blk_start, name_len)) { + if (!strncasecmp("Allow", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Allow\n"); if (!strncmp("204", value_start, 3)) { s->flags.allow_204 = 1; } else { debug(81, 3) ("icapOptParseEntry: Allow value unknown"); } - } else if (!strncmp("Connection", blk_start, name_len)) { + } else if (!strncasecmp("Connection", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Connection\n"); - } else if (!strncmp("Encapsulated", blk_start, name_len)) { + } else if (!strncasecmp("Encapsulated", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Encapsulated\n"); - } else if (!strncmp("ISTAG", blk_start, name_len)) { + } else if (!strncasecmp("ISTAG", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found ISTAG\n"); stringClean(&s->istag); stringLimitInit(&s->istag, value_start, value_len); - } else if (!strncmp("Max-Connections", blk_start, name_len)) { + } else if (!strncasecmp("Max-Connections", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Max-Connections\n"); errno = 0; new = strtol(value_start, NULL, 10); @@ -389,9 +389,9 @@ debug(81, 5) ("icapOptParseEntry: Max-Connections: new value=%d\n", new); s->max_connections = new; } - } else if (!strncmp("Methods", blk_start, name_len)) { + } else if (!strncasecmp("Methods", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Methods\n"); - } else if (!strncmp("Options-TTL", blk_start, name_len)) { + } else if (!strncasecmp("Options-TTL", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Options-TTL\n"); errno = 0; new = strtol(value_start, NULL, 10); @@ -401,7 +401,7 @@ debug(81, 5) ("icapOptParseEntry: Options-TTL: new value=%d\n", new); s->options_ttl = new; } - } else if (!strncmp("Preview", blk_start, name_len)) { + } else if (!strncasecmp("Preview", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Preview\n"); errno = 0; new = strtol(value_start, NULL, 10); @@ -411,23 +411,23 @@ debug(81, 5) ("icapOptParseEntry: Preview: new value=%d\n", new); s->preview = new; } - } else if (!strncmp("Service", blk_start, name_len)) { + } else if (!strncasecmp("Service", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Service\n"); - } else if (!strncmp("Service-ID", blk_start, name_len)) { + } else if (!strncasecmp("Service-ID", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Service-ID\n"); - } else if (!strncmp("Transfer-Preview", blk_start, name_len)) { + } else if (!strncasecmp("Transfer-Preview", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Transfer-Preview\n"); stringClean(&s->transfer_preview); stringLimitInit(&s->transfer_preview, value_start, value_len); - } else if (!strncmp("Transfer-Ignore", blk_start, name_len)) { + } else if (!strncasecmp("Transfer-Ignore", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Transfer-Ignore\n"); stringClean(&s->transfer_ignore); stringLimitInit(&s->transfer_ignore, value_start, value_len); - } else if (!strncmp("Transfer-Complete", blk_start, name_len)) { + } else if (!strncasecmp("Transfer-Complete", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found Transfer-Complete\n"); stringClean(&s->transfer_complete); stringLimitInit(&s->transfer_complete, value_start, value_len); - } else if (!strncmp("X-Include", blk_start, name_len)) { + } else if (!strncasecmp("X-Include", blk_start, name_len)) { debug(81, 5) ("icapOptParseEntry: found X-Include\n"); } else { debug(81, 5) ("icapOptParseEntry: unknown options header\n"); @@ -455,7 +455,7 @@ debug(81, 3) ("icapOptParseReply: got reply: <ICAP/%1.1f %d %s>\n", ver, status, tmpbuf); if (status != 200) { - debug(81, 3) ("icapOptParseReply: status = %d != 200", status); + debug(81, 3) ("icapOptParseReply: status = %d != 200\n", status); return 0; } parse_start = buf; Index: src/icap_reqmod.c =================================================================== RCS file: /cvsroot/squid/squid/src/Attic/icap_reqmod.c,v retrieving revision 1.1.2.28 diff -u -r1.1.2.28 icap_reqmod.c --- src/icap_reqmod.c 13 May 2004 16:26:19 -0000 1.1.2.28 +++ src/icap_reqmod.c 15 Jun 2004 11:31:33 -0000 @@ -619,9 +619,9 @@ memBufPrintf(&mb, "Encapsulated: req-hdr=0"); /* TODO: Change the offset using 'request' if needed */ if (icap->request->content_length > 0) - memBufPrintf(&mb, ", req-body=%d", mb_hdr.size); + memBufPrintf(&mb, ", req-body=%d", mb_hdr.size+2); else - memBufPrintf(&mb, ", null-body=%d", mb_hdr.size); + memBufPrintf(&mb, ", null-body=%d", mb_hdr.size+2); memBufAppend(&mb, crlf, 2); if (Config.icapcfg.send_client_ip) memBufPrintf(&mb, "X-Client-IP: %s\r\n", client_addr); Index: src/icap_respmod.c =================================================================== RCS file: /cvsroot/squid/squid/src/Attic/icap_respmod.c,v retrieving revision 1.1.2.34 diff -u -r1.1.2.34 icap_respmod.c --- src/icap_respmod.c 13 May 2004 16:26:20 -0000 1.1.2.34 +++ src/icap_respmod.c 15 Jun 2004 11:31:36 -0000 @@ -38,6 +38,7 @@ static CWCB icapSendRespModDone; static PF icapRespModGobble; extern PF icapReadReply; +static PF icapRespModReadReply; static int icapReadReply2(IcapStateData * icap); static void icapReadReply3(IcapStateData * icap); @@ -46,7 +47,7 @@ static void getICAPRespModString(MemBuf * mb, int o1, int o2, int o3, char *service, char *client_addr, - IcapStateData * icap) + IcapStateData * icap, int allow_204) { memBufPrintf(mb, "RESPMOD %s ICAP/1.0\r\nEncapsulated:", service); if (o1 >= 0) @@ -58,7 +59,7 @@ else memBufPrintf(mb, ", null-body=%1d", -o3); - memBufPrintf(mb, "\r\n"); + memBufPrintf(mb, crlf); if (Config.icapcfg.send_client_ip) { memBufPrintf(mb, "X-Client-IP: %s\r\n", client_addr); } @@ -70,6 +71,8 @@ memBufPrintf(mb, "X-TE: trailers\r\n"); } #endif + if (allow_204) + memBufPrintf(mb, "Allow: 204\r\n"); } static int @@ -131,9 +134,9 @@ icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r); httpReplyDestroy(r); if (icap->respmod.res_body_sz) - getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr, icap); + getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr, icap, service->flags.allow_204); else - getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr, icap); + getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr, icap, service->flags.allow_204); if (Config.icapcfg.preview_enable) if (icap->preview_size >= 0) memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size); @@ -240,7 +243,7 @@ if (size > preview_size + 1) size = preview_size + 1; size -= icap->respmod.buffer.size; - debug(81, 3) ("icapSendRespMod: FD %d: copy %d more bytes to preview buffer.\n", icap->http_fd, size); + debug(81, 3) ("icapSendRespMod: FD %d: copy %d more bytes to preview buffer.\n", icap->icap_fd, size); memBufAppend(&icap->respmod.buffer, buf, size); buf = ((char *) buf) + size; len -= size; @@ -259,7 +262,8 @@ } if (icap->respmod.buffer.size <= preview_size) { /* content length is less than preview size+1 */ - memBufAppend(&mb, "0; ieof\r\n\r\n", 11); + if (icap->respmod.res_body_sz) + memBufAppend(&mb, "0; ieof\r\n\r\n", 11); memBufReset(&icap->respmod.buffer); /* will now be used for other data */ } else { char ch; @@ -270,7 +274,7 @@ ch = icap->respmod.buffer.buf[preview_size]; memBufReset(&icap->respmod.buffer); /* will now be used for other data */ memBufAppend(&icap->respmod.buffer, &ch, 1); - debug(81, 3) ("icapSendRespMod: FD %d: sending preview and keeping %d bytes in internal buf.\n", icap->http_fd, len + 1); + debug(81, 3) ("icapSendRespMod: FD %d: sending preview and keeping %d bytes in internal buf.\n", icap->icap_fd, len + 1); if (len > 0) memBufAppend(&icap->respmod.buffer, buf, len); } @@ -280,15 +284,15 @@ } else if (icap->flags.wait_for_preview_reply) { /* received new data while waiting for preview response */ /* add data to internal buffer and send later */ - debug(81, 3) ("icapSendRespMod: FD %d: add %d more bytes to internal buf while wiaiting for preview-response.\n", icap->http_fd, len); + debug(81, 3) ("icapSendRespMod: FD %d: add %d more bytes to internal buf while waiting for preview-response.\n", icap->icap_fd, len); if (len > 0) memBufAppend(&icap->respmod.buffer, buf, len); /* do not send any data now while waiting for preview response */ /* but prepare for read more data on the HTTP connection */ if (!icap->flags.http_server_eof) { - debug(81, 3) ("icapSendRespMod: FD %d: commSetSelect on read httpReadReply waiting for preview response.\n", icap->http_fd); - commSetSelect(icap->http_fd, COMM_SELECT_READ, httpReadReply, - httpState, 0); + debug(81, 3) ("icapSendRespMod: FD %d: commSetSelect on read icapRespModReadReply waiting for preview response.\n", icap->icap_fd); + commSetSelect(icap->icap_fd, COMM_SELECT_READ, icapRespModReadReply, + icap, 0); } return; } else @@ -395,17 +399,22 @@ * was received while waiting fot this ICAP response */ icapSendRespMod(icap, NULL, 0, 0); + /* reset the header to send the rest of the preview */ + if (!memBufIsNull(&icap->icap_hdr)) + memBufReset (&icap->icap_hdr); return; #if SUPPORT_ICAP_204 } else if (status == 204) { + debug(81, 5) ("icapRespModReadReply: 204 No modification received\n"); + icap->flags.wait_for_preview_reply = 0; if (icap->flags.http_server_eof) { /* Reset is required to avoid duplicate stmemFreeDataUpto , * but will I loose all info now ? */ /* storeEntryReset(icap->respmod.entry); */ /* stmemFreeDataUpto(&(entry->mem_obj->data_hdr), -icap->sc); */ - fwdComplete(httpState->fwd); + fwdComplete(icap->httpState->fwd); } else { - commSetSelect(fd, COMM_SELECT_READ, httpReadReply, + commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0); } comm_close(fd); @@ -454,7 +463,7 @@ if (icapFindHeader(icap->icap_hdr.buf, "Encapsulated:", &start, &end)) { icapParseEncapsulated(icap, start, end); } else { - debug(81, 1) ("WARNING: icapReqModReadReply() did not find 'Encapsulated' header\n"); + debug(81, 1) ("WARNING: icapRespModReadReply() did not find 'Encapsulated' header\n"); } if (icap->enc.res_hdr > -1) directResponse = 1; @@ -895,6 +904,7 @@ * there's nothing for us to do. */ (void) 0; + comm_close (fd); } else if (icapPconnTransferDone(fd, icap)) { /* yes we have to clear all these! */ commSetDefer(fd, NULL, NULL); Index: src/squid.h =================================================================== RCS file: /cvsroot/squid/squid/src/squid.h,v retrieving revision 1.13.6.6.2.2 diff -u -r1.13.6.6.2.2 squid.h --- src/squid.h 27 Jun 2003 01:15:19 -0000 1.13.6.6.2.2 +++ src/squid.h 15 Jun 2004 11:31:37 -0000 @@ -38,12 +38,12 @@ #include "config.h" /* - * experimental defines for ICAP; apparently this Squid-Icap *requires* - * ICAP_CHUNKED : Basile Starynkevitch, june 14th 2002 + * experimental defines for ICAP */ #ifdef HS_FEAT_ICAP -#define ICAP_CHUNKED 1 +#define ICAP_PREVIEW 1 +#define SUPPORT_ICAP_204 1 #endif /* * On some systems, FD_SETSIZE is set to something lower than the