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 bugsI'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
