squid 2.5 with icap (fwd)

From: Henrik Nordstrom <hno@dont-contact.us>
Date: Sat, 14 May 2005 01:21:52 +0200 (CEST)

attached mail follows:


Hello Henrik,

I dont know who is responsible for icapclient development in squid, if
not you are, please forward it.

We have been using the squid with icap support. We found the following
problem in squid icap client:
When an HTTP server sends a response to squid without HTTP header
(according to HTTP/0.9),
squid makes wrong icap request, so an icapserver cannot parse it. The
HTTP part of squid works good with such request, but the icap client
does not.
Unfortunatelly there are HTTP servers that uses this old protocol.

For example:

RESPMOD icap://localhost:1025/ ICAP/1.0
Encapsulated: req-hdr=0, res-hdr=567, res-body=820
Allow: 204
Connection: keep-alive

GET /SOME_URL HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/vnd.ms-excel, application/msword,
application/vnd.ms-powerpoint, application/x-shockwave-flash, */*
Referer: http://rt.fortuneo.fr/FrNR3tamfqEgh6Lx36/WIrU
Accept-Language: fr
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon;
.NET CLR 1.1.4322)
Host: rt.fortuneo.fr
Via: 1.0 SDA2:3128 (squid/2.5.STABLE6), 1.0 antiv2:3128
(squid/2.5.STABLE9-CVS)
Cache-Control: max-age=259200

<html><script>parent(SKIPPED);</script></html>

0

Sorry, the private information in the icap request is skipped.
We made a patch to fix this problem, and would like somebody to add it
to the squid icap development branch.

-- 
 
 With Best Regards,
 Sergey Ivanov
 Software Engineer /Kaspersky Lab.Ltd,
 __________________________________________________
 10, Geroyev Panfilovtsev Str., 125363, Moscow, Russia
 Tel.: +7 095 797-8700; Fax: +7 095 948-4331;
 http://www.kaspersky.com; http://www.viruslist.com

diff -Nuar squid-icap-2.5/src/HttpStatusLine.c squid-icap-2.5-new/src/HttpStatusLine.c
--- squid-icap-2.5/src/HttpStatusLine.c 2002-09-24 01:46:16.000000000 +0400
+++ squid-icap-2.5-new/src/HttpStatusLine.c 2005-05-13 17:54:47.000000000 +0400
@@ -85,8 +85,12 @@
 {
     assert(sline);
     sline->status = HTTP_INVALID_HEADER; /* Squid header parsing error */
- if (strncasecmp(start, "HTTP/", 5))
+ if (strncasecmp(start, "HTTP/", 5)){
+ if (end - start > 4)
+ httpBuildVersion(&sline->version, 0, 9);
+
         return 0;
+ }
     start += 5;
     if (!xisdigit(*start))
         return 0;
diff -Nuar squid-icap-2.5/src/icap_respmod.c squid-icap-2.5-new/src/icap_respmod.c
--- squid-icap-2.5/src/icap_respmod.c 2005-05-12 12:26:09.000000000 +0400
+++ squid-icap-2.5-new/src/icap_respmod.c 2005-05-13 20:00:02.000000000 +0400
@@ -52,7 +52,7 @@
     memBufPrintf(mb, "RESPMOD %s ICAP/1.0\r\nEncapsulated:", service->uri);
     if (o1 >= 0)
         memBufPrintf(mb, " req-hdr=%1d", o1);
- if (o2 >= 0)
+ if (o2 >= 0 && o2!=o3)
         memBufPrintf(mb, ", res-hdr=%1d", o2);
     if (o3 >= 0)
         memBufPrintf(mb, ", res-body=%1d", o3);
@@ -89,6 +89,8 @@
     int consumed;
     icap_service *service;
     HttpReply *r;
+ HttpStatusLine sline;
+
 
     if (memBufIsNull(&icap->respmod.req_hdr_copy))
         memBufDefInit(&icap->respmod.req_hdr_copy);
@@ -98,21 +100,31 @@
         icap->respmod.req_hdr_copy.size);
     debug(81, 3) ("buildRespModHeader: headersEnd = %d\n", hlen);
     if (0 == hlen)
- return 0;
+ return (-1);
+
+ httpStatusLineParse(&sline,icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.buf+
+ icap->respmod.req_hdr_copy.size);
 
+ if (sline.version.major == 0 && sline.version.minor == 9) {
+ debug(81, 5) ("icapSendRespMod: Non-HTTP-compliant header found, set hlen=0\n");
+ hlen = 0;
+ icap->respmod.res_body_sz = icap->respmod.req_hdr_copy.size;
+ }
+
     /*
- * calc how many bytes from this 'buf' went towards the
+ * calc how many bytes from this 'bu/cons/consuuf' went towards the
      * reply header.
      */
- consumed = hlen - (icap->respmod.req_hdr_copy.size - len);
+ consumed = hlen?hlen - (icap->respmod.req_hdr_copy.size - len):0;
+
     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;
+ if (hlen < icap->respmod.req_hdr_copy.size)
+ icap->respmod.req_hdr_copy.size = hlen;
 
     /* Copy request header */
     memBufDefInit(&mb_hdr);
@@ -121,19 +133,20 @@
     o2 = mb_hdr.size;
 
     /* Copy response header - Append to request header mbuffer */
- memBufAppend(&mb_hdr,
- icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size);
+ if (hlen) memBufAppend(&mb_hdr,icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size);
+
     o3 = mb_hdr.size;
 
     service = icap->current_service;
     assert(service);
     client_addr = inet_ntoa(icap->request->client_addr);
 
- r = httpReplyCreate();
- httpReplyParse(r, icap->respmod.req_hdr_copy.buf,
- icap->respmod.req_hdr_copy.size);
- icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r);
- httpReplyDestroy(r);
+ if (hlen) {
+ r = httpReplyCreate();
+ httpReplyParse(r, icap->respmod.req_hdr_copy.buf,icap->respmod.req_hdr_copy.size);
+ icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r);
+ httpReplyDestroy(r);
+ }
     if (icap->respmod.res_body_sz)
         getICAPRespModString(mb, 0, o2, o3, client_addr, icap, service);
     else
@@ -228,14 +241,16 @@
     }
     if (icap->sc == 0) {
         /* No data sent yet. Start with headers */
- icap->sc = buildRespModHeader(&mb, icap, buf, len, theEnd);
- buf += icap->sc;
- len -= icap->sc;
+ if ((icap->sc = buildRespModHeader(&mb, icap, buf, len, theEnd))>=0) {
+ buf += icap->sc;
+ len -= icap->sc;
+ }
     }
- if (0 == icap->sc) {
+ if (-1 == icap->sc) {
         /* check again; bail if we're not ready to send ICAP/HTTP hdrs */
         debug(81, 5) ("icapSendRespMod: dont have full HTTP response hdrs\n");
         memBufClean(&mb);
+ icap->sc = 0;
         return;
     }
 #if ICAP_PREVIEW
@@ -878,6 +893,8 @@
         icapReadReply3(icap);
         return 0;
     }
+
+
     if (icapHttpReplyHdrState(icap) == 0) {
         int expect = icapExpectedHttpReplyHdrSize(icap);
         int so_far = icap->http_header_bytes_read_so_far;
@@ -889,6 +906,8 @@
         if (0 > expect) {
             icapProcessHttpReplyHeader(icap,
                 icap->chunk_buf.buf, icap->chunk_buf.size);
+ icap->chunk_size = 0;
+
         } else if (0 == expect) {
             /*
              * this icap reply doesn't give us new HTTP headers
@@ -940,8 +959,9 @@
             icap->chunk_buf.size = 0;
         }
     } else if (2 == icapHttpReplyHdrState(icap)) {
- if (icap->chunk_buf.size)
+ if (icap->chunk_buf.size) {
             icapParseChunkedBody(icap, (STRCB *) storeAppend, entry);
+ }
     }
     icapReadReply3(icap);
     return 0;
Received on Fri May 13 2005 - 17:21:55 MDT

This archive was generated by hypermail pre-2.1.9 : Tue May 31 2005 - 12:00:03 MDT