Search squid archive

Re: [squid-users] 2 Content-Length headers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 29 Mar 2005, Tracey, Michael wrote:

I've got a site that is required in our business flow that I can not change:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Tue, 29 Mar 2005 19:15:38 GMT
Content-type: image/jpeg
Content-length: 38233
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
Content-Length: 39145

Squid chokes on the two Content-Length headers:

2005/03/29 14:18:20| ctx: enter level  0: 'http://url/'
2005/03/29 14:18:20| WARNING: found two conflicting content-length headers
2005/03/29 14:18:20| ctx: exit level  0

Any way that I can get squid allow access to content with two Content-Length
headers?

Have been pondering about this problem for a while and came up with the attached patch as a possible solution. This patch cleans up the "bad" content-length headers when relaxed_header_parser is enabled (on/warn setting, default is on).


I have also considered making yet another access lists for this but in the end decided not to (both more complex to implement and hard to configure right).

The effects of the patch has not yet been fully evaluated to make sure it doesn't open opportunities for launching the response splitting or request hiding families of attacks on Squid but from an quick evaluation it looks safe.

Regards
Henrik
Index: src/HttpHeader.c
===================================================================
RCS file: /cvsroot/squid/squid/src/HttpHeader.c,v
retrieving revision 1.74.2.28
diff -u -p -r1.74.2.28 HttpHeader.c
--- src/HttpHeader.c	6 May 2005 21:32:09 -0000	1.74.2.28
+++ src/HttpHeader.c	18 May 2005 15:47:10 -0000
@@ -475,9 +475,25 @@ httpHeaderParse(HttpHeader * hdr, const 
 	}
 	if (e->id == HDR_CONTENT_LENGTH && (e2 = httpHeaderFindEntry(hdr, e->id)) != NULL) {
 	    if (strCmp(e->value, strBuf(e2->value)) != 0) {
-		debug(55, 1) ("WARNING: found two conflicting content-length headers in {%s}\n", getStringPrefix(header_start, header_end));
-		httpHeaderEntryDestroy(e);
-		return httpHeaderReset(hdr);
+		squid_off_t l1, l2;
+		debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2) ("WARNING: found two conflicting content-length headers in {%s}\n", getStringPrefix(header_start, header_end));
+		if (!Config.onoff.relaxed_header_parser) {
+		    httpHeaderEntryDestroy(e);
+		    return httpHeaderReset(hdr);
+		}
+		if (!httpHeaderParseSize(strBuf(e->value), &l1)) {
+		    debug(55, 1)("WARNING: Unparseable content-length '%s'\n", strBuf(e->value));
+		    httpHeaderEntryDestroy(e);
+		    continue;
+		} else if (!httpHeaderParseSize(strBuf(e2->value), &l2)) {
+		    debug(55, 1)("WARNING: Unparseable content-length '%s'\n", strBuf(e2->value));
+		    httpHeaderDelById(hdr, e2->id);
+		} else if (l1 > l2) {
+		    httpHeaderDelById(hdr, e2->id);
+		} else {
+		    httpHeaderEntryDestroy(e);
+		    continue;
+		}
 	    } else {
 		debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
 		    ("NOTICE: found double content-length header\n");

[Index of Archives]     [Linux Audio Users]     [Samba]     [Big List of Linux Books]     [Linux USB]     [Yosemite News]

  Powered by Linux