Пример #1
0
/* add extension header (these fields are not parsed/analyzed/joined, etc.) */
void
httpHeaderPutExt(HttpHeader * hdr, const char *name, const char *value)
{
    assert(name && value);
    debug(55, 8) ("%p adds ext entry '%s: %s'\n", hdr, name, value);
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(HDR_OTHER, name, value));
}
Пример #2
0
// send check header  "X-CC-DOWN-CHECK" to lower FC
static int SendCheckHeader(clientHttpRequest *http)
{
	// do not send X-CC-UP-CHECK to client as possible
	httpHeaderDelByName(&http->reply->header, "X-CC-UP-CHECK");

	struct mod_conf_param *cfg = cc_get_mod_param(http->conn->fd, mod);
	if (NULL == cfg || !cfg->send) {
		debug(107,3)("mod_check_response: no need to send X-CC-UP-CHECK header\n");
		return -1;
	}

	const char *down_buf = httpHeaderGetValue(&http->request->header, "X-CC-DOWN-CHECK");
	if (NULL == down_buf) {
		if (cfg->send)
			debug(107,2)("mod_check_response: do not send X-CC-UP-CHECK header, for not received X-CC-DOWN-CHECK header\n");
		return -1;
	}

	char key[512];  
	memset(key, 0, 512);
	unsigned char md5[SQUID_MD5_DIGEST_LENGTH];
	memset(md5, 0, SQUID_MD5_DIGEST_LENGTH);

	strncpy(key, down_buf, 511);
	char *host = key + strlen(key);
	url2host(host, http->uri);
	GetMD5Digest(key, md5);

	assert(cfg->send);
	httpHeaderAddEntry(&http->reply->header, httpHeaderEntryCreate(HDR_OTHER, "X-CC-UP-CHECK", (char*)md5));
	debug(107, 3)("mod_check_response: send X-CC-UP-CHECK=[%s] header to client\n", md5);
	return 0;
}
Пример #3
0
static int func_http_repl_send_start(clientHttpRequest *http)
{
	assert(http);
    if (0 == http->request->flags.redirected)
        return -1;

    HttpHeader *hdr = &http->reply->header;
    HttpHeaderEntry e;
    stringInit(&e.name,"Content-Disposition");
    stringInit(&e.value,"attachment; filename=\"");

    char *filename = strrchr(http->uri, '/');
    if (NULL == filename)
        return -1;
    filename++;
    stringAppend(&e.value, filename, strlen(filename));
    stringAppend(&e.value, "\"", 1);

    e.id = HDR_CONTENT_DISPOSITION;
    httpHeaderDelById(hdr, e.id);  
    httpHeaderAddEntry(hdr, httpHeaderEntryClone(&e));
    stringClean(&e.name);
    stringClean(&e.value);
	return 0;
}
Пример #4
0
void
httpHeaderPutTime(HttpHeader * hdr, http_hdr_type id, time_t htime)
{
    assert_eid(id);
    assert(Headers[id].type == ftDate_1123);	/* must be of an appropriate type */
    assert(htime >= 0);
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(id, NULL, mkrfc1123(htime)));
}
Пример #5
0
void
httpHeaderPutInt(HttpHeader * hdr, http_hdr_type id, int number)
{
    assert_eid(id);
    assert(Headers[id].type == ftInt);	/* must be of an appropriate type */
    assert(number >= 0);
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(id, NULL, xitoa(number)));
}
Пример #6
0
void
httpHeaderPutStr(HttpHeader * hdr, http_hdr_type id, const char *str)
{
    assert_eid(id);
    assert(Headers[id].type == ftStr);	/* must be of an appropriate type */
    assert(str);
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(id, NULL, str));
}
Пример #7
0
void
httpHeaderPutSize(HttpHeader * hdr, http_hdr_type id, squid_off_t number)
{
    char size[64];
    assert_eid(id);
    assert(Headers[id].type == ftSize);		/* must be of an appropriate type */
    assert(number >= 0);
    snprintf(size, sizeof(size), "%" PRINTF_OFF_T, number);
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(id, NULL, size));
}
Пример #8
0
/* append entries (also see httpHeaderUpdate) */
void
httpHeaderAppend(HttpHeader * dest, const HttpHeader * src)
{
    const HttpHeaderEntry *e;
    HttpHeaderPos pos = HttpHeaderInitPos;
    assert(src && dest);
    assert(src != dest);
    debug(55, 7) ("appending hdr: %p += %p\n", dest, src);

    while ((e = httpHeaderGetEntry(src, &pos))) {
	httpHeaderAddEntry(dest, httpHeaderEntryClone(e));
    }
}
Пример #9
0
/*
 *This line is to modify the header
 */
static int mod_modify_s2o_header(HttpStateData* data, HttpHeader* hdr)
{
	assert(data);
	int fd = data->fd;
	int i, len;

	struct mod_conf_param *param = (struct mod_conf_param *)cc_get_mod_param(fd, mod);
	assert(param);

	debug(107, 3)("param->orig_name=%s, param->new_name=%s\n", strBuf(param->orig_name), strBuf(param->new_name));
	HttpHeaderPos pos = HttpHeaderInitPos;
	HttpHeaderEntry *myheader;
	HttpHeaderEntry e;

	while ((myheader = httpHeaderGetEntry(hdr, &pos)))
	{
		debug(107, 3)("myheader=%s, param->new_name=%s\n", strBuf(myheader->name), strBuf(param->new_name));
		if (strCaseCmp(myheader->name, strBuf(param->orig_name)) == 0)
		{
			debug(107, 3)("%s is myheader->value,%s is param->orig_name\n",strBuf(myheader->value), strBuf(param->orig_name));

			if(strLen(myheader->value) >= 4095)
			{
				debug(107, 3)("A too long header value!!\n");
				return -1;
			}

			stringInit(&e.name, strBuf(param->new_name));
			stringInit(&e.value, myheader->value.buf);
			len=strlen(strBuf(e.name));
			i=httpHeaderIdByNameDef(strBuf(e.name), len);
			if(-1 == i)
				e.id = HDR_OTHER;
			else    
				e.id = i;
			httpHeaderDelByName(hdr, strBuf(param->orig_name));
			httpHeaderAddEntry(hdr, httpHeaderEntryClone(&e));
			//httpHeaderDelAt(&request->header, pos);
			//httpHeaderRefreshMask(&request->header);
			//httpHeaderInsertEntry(&request->header, httpHeaderEntryClone(&e), pos);
			stringClean(&e.name);
			stringClean(&e.value);			
			break;
		}
	}
	return 0;

}
Пример #10
0
/* use fresh entries to replace old ones */
void
httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask)
{
    const HttpHeaderEntry *e;
    HttpHeaderPos pos = HttpHeaderInitPos;
    assert(old && fresh);
    assert(old != fresh);
    debug(55, 7) ("updating hdr: %p <- %p\n", old, fresh);

    while ((e = httpHeaderGetEntry(fresh, &pos))) {
	/* deny bad guys (ok to check for HDR_OTHER) here */
	if (denied_mask && CBIT_TEST(*denied_mask, e->id))
	    continue;
	httpHeaderDelByName(old, strBuf(e->name));
	httpHeaderAddEntry(old, httpHeaderEntryClone(e));
    }
}
Пример #11
0
void
httpHeaderPutRange(HttpHeader * hdr, const HttpHdrRange * range)
{
    MemBuf mb;
    Packer p;
    assert(hdr && range);
    /* remove old directives if any */
    httpHeaderDelById(hdr, HDR_RANGE);
    /* pack into mb */
    memBufDefInit(&mb);
    packerToMemInit(&p, &mb);
    httpHdrRangePackInto(range, &p);
    /* put */
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(HDR_RANGE, NULL, mb.buf));
    /* cleanup */
    packerClean(&p);
    memBufClean(&mb);
}
Пример #12
0
void
httpHeaderPutCc(HttpHeader * hdr, const HttpHdrCc * cc)
{
    MemBuf mb;
    Packer p;
    assert(hdr && cc);
    /* remove old directives if any */
    httpHeaderDelById(hdr, HDR_CACHE_CONTROL);
    /* pack into mb */
    memBufDefInit(&mb);
    packerToMemInit(&p, &mb);
    httpHdrCcPackInto(cc, &p);
    /* put */
    httpHeaderAddEntry(hdr, httpHeaderEntryCreate(HDR_CACHE_CONTROL, NULL, mb.buf));
    /* cleanup */
    packerClean(&p);
    memBufClean(&mb);
}
Пример #13
0
int
httpHeaderParse(HttpHeader * hdr, const char *header_start, const char *header_end)
{
    const char *field_start = header_start;
    HttpHeaderEntry *e;

    assert(hdr);
    assert(header_start && header_end);
    debug(55, 7) ("parsing hdr: (%p)\n%s\n", hdr, getStringPrefix(header_start, header_end));
    HttpHeaderStats[hdr->owner].parsedCount++;
    /* commonn format headers are "<name>:[ws]<value>" lines delimited by <CRLF> */
    while (field_start < header_end) {
	const char *field_end;
	const char *field_ptr = field_start;
	do {
	    field_end = field_ptr = field_ptr + strcspn(field_ptr, "\r\n");
	    /* skip CRLF */
	    if (*field_ptr == '\r')
		field_ptr++;
	    if (*field_ptr == '\n')
		field_ptr++;
	}
	while (*field_ptr == ' ' || *field_ptr == '\t');
	if (!*field_end || field_end > header_end)
	    return httpHeaderReset(hdr);	/* missing <CRLF> */
	e = httpHeaderEntryParseCreate(field_start, field_end);
	if (e != NULL)
	    httpHeaderAddEntry(hdr, e);
	else
	    debug(55, 2) ("warning: ignoring unparseable http header field near '%s'\n",
		getStringPrefix(field_start, field_end));
	field_start = field_end;
	/* skip CRLF */
	if (*field_start == '\r')
	    field_start++;
	if (*field_start == '\n')
	    field_start++;
    }
    return 1;			/* even if no fields where found, it is a valid header */
}
Пример #14
0
// send a special header to upper FC
static int SendRandomNumber(HttpStateData *httpState, HttpHeader* hdr)
{
	struct mod_conf_param *cfg = cc_get_mod_param(httpState->fd, mod);
	if (NULL == cfg)
		return -1;

	struct timeval tp;
	if (gettimeofday(&tp, NULL)) {
		debug(107, 2)("mod_check_response: gettimeofday error\n");
		return -1;
	}

	struct send_random *data = cc_get_mod_private_data(FWDSTATE_PRIVATE_DATA, httpState->fwd, mod);
	if (!data) {
		data = xcalloc(1, sizeof(struct send_random));
		snprintf(data->number, 10, "%ld", tp.tv_usec);
		cc_register_mod_private_data(FWDSTATE_PRIVATE_DATA, httpState->fwd, data, free_random, mod);
		httpHeaderAddEntry(hdr, httpHeaderEntryCreate(HDR_OTHER, "X-CC-DOWN-CHECK", data->number));
		debug(107,3)("mod_check_response: send X-CC-DOWN-CHECK=[%s] to orgin\n", data->number);
	}
	return 0;
}
Пример #15
0
void
httpHeaderAddClone(HttpHeader * hdr, const HttpHeaderEntry * e)
{
    httpHeaderAddEntry(hdr, httpHeaderEntryClone(e));
}
Пример #16
0
/*if the origindomain doesn't need cookie,this part is not neccessary 
 *
static int update_cookie_direction_0(clientHttpRequest *http)
{
	assert(http);
	assert(http->request);

	const char head_name_request[20] = "Cookie";
	int len = strlen(head_name_request);
	int flag = 0;
	HttpHeaderPos pos = HttpHeaderInitPos;

	request_t* request = http->request;

	char *uri = http->uri;
	char cookie_value[100]="0";
	
	char cookie_primary_key_name[20];
	char cookie_sub_key_name[20];
	int i = 0;

	debug(139,3)("in update_cookie_direction_0 receive uri %s\n",uri);

	HttpHeaderEntry e;
	HttpHeaderEntry *myheader;

	stringInit(&e.name, head_name_request);
	i = httpHeaderIdByNameDef(head_name_request, len);
	e.id = i;
	if (-1 == i)
		e.id = HDR_OTHER; 
	while ((myheader = httpHeaderGetEntry(&request->header, &pos))) 
	{
		if (strCaseCmp(myheader->name, head_name_request) == 0)
		{
			debug(139, 3)("%s is myheader->value,%s is name\n",myheader->value.buf,myheader->name.buf);
			flag = 1;
		}
	}

	debug(139,3)("flag=%d\n",flag);
	if(!flag)
	{
		if(0 == get_param_from_uri(uri,cookie_primary_key_name,cookie_sub_key_name))
		{
			return 1;
		}
		to_upper(cookie_primary_key_name);
		snprintf(cookie_value,100,"%s:(FM%s=0)",cookie_primary_key_name,cookie_sub_key_name);
		debug(139,3)("cookie value is %s\n",cookie_value);
		debug(139,3)("cookie_primary_key_name is %s\n",cookie_primary_key_name);
		debug(139,3)("cookie_sub_key_name is %s\n",cookie_sub_key_name);
		stringInit(&e.value, cookie_value);
		httpHeaderAddEntry(&request->header, httpHeaderEntryClone(&e));
	}
	return 1;
}
*/
static int update_cookie_direction_3(clientHttpRequest *http)
{
	assert(http);
	assert(http->request);

//	const char head_name_request[20] = "Cookie";
	const char head_name_reply[20] = "Set-Cookie";
//	int len = strlen(head_name_reply);
//	int flag = 0;
//	HttpHeaderPos pos = HttpHeaderInitPos;

//	request_t* request = http->request;
	HttpReply* reply = http->reply; 

	char *uri = http->uri;
//	char cookie_value[MAX_NAME_SIZE] = "0";
//	char cookie_value_from_url[MAX_NAME_SIZE] = "0 ";
	char cookie_primary_key_name[MAX_NAME_SIZE] = "0";
	char cookie_sub_key_name[MAX_NAME_SIZE] = "0";
	char cookie_file_name[MAX_NAME_SIZE] = "0";

	debug(139,3)("in update_cookie_direction_3 receive uri %s\n",uri);

	HttpHeaderEntry e;
//	HttpHeaderEntry *myheader;

	stringInit(&e.name, head_name_reply);
//	i = httpHeaderIdByNameDef(head_name_reply, len);
//	e.id = i;
	e.id = HDR_SET_COOKIE;
//	if (-1 == i)
//		e.id = HDR_OTHER; 
	/*
	while ((myheader = httpHeaderGetEntry(&request->header, &pos))) 
	{
		if (strCaseCmp(myheader->name, head_name_request) == 0)
		{
			debug(139, 3)("%s is myheader->value,%s is name\n",myheader->value.buf,myheader->name.buf);
			flag = 1;
			strcpy(cookie_value,myheader->value.buf);
			debug(139,5)("cookie_value =%s\n",cookie_value);
			if(0 == deal_with_cookie(cookie_value))
			{
				debug(139,3)("Cookie format is wrong\n");
				return 0;
			}
			if(0 == get_param_from_uri(uri,cookie_primary_key_name,cookie_sub_key_name))
			{
				debug(139,3)("get_param_from_uri error\n");
				return 0;
			}
			to_upper(cookie_primary_key_name);
			snprintf(cookie_value_from_url,100,"%s:(FM%s=",cookie_primary_key_name,cookie_sub_key_name);
			debug(139,5)("cookie_value_from_url is %s\n",cookie_value_from_url);
			if(strncmp(cookie_value,cookie_value_from_url,strlen(cookie_value_from_url)))
			{
				debug(139,3)("get_param_from_uri cookie_value_from_url doesn't match cookie_value\n");
				return 0;
			}

		}
	}
	*/

	if(reply->sline.status >= HTTP_OK && reply->sline.status < HTTP_BAD_REQUEST )
	{
		if(0 == get_param_from_uri(uri,cookie_primary_key_name,cookie_sub_key_name,cookie_file_name))
		{
			debug(139,3)("get_param_from_uri error\n");
			stringClean(&e.name);
			return 0;
		}
		struct tm *ptr;  
		ptr = gmtime(&reply->expires);  

		debug(139,3)("expires = %s\n", asctime(ptr));

		char tmpbuf[128];
		char cookie_value[MAX_HEADER_SIZE];

		strftime( tmpbuf, 128, "%a, %d %b %G %T GMT \n", ptr); 
		debug(139,3)("expires = %s\n", tmpbuf);
		snprintf(cookie_value,MAX_HEADER_SIZE,"DTAG=CAM=%s&LOC=%s&CRT=%s; expires=%s; path=/",cookie_primary_key_name,cookie_sub_key_name,cookie_file_name,tmpbuf);
		
		debug(139,5)("cookie value is %s\n",cookie_value);
		stringInit(&e.value, cookie_value);
		httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
		stringClean(&e.value);
	}
	else
	{
		;//do nothing
	}
	stringClean(&e.name);


	return 1;
}
Пример #17
0
/*
 *?????Ǵ????޸ġ?????һ??header?Ĵ??�??
 */
static int modifyHeader3(struct action_part* acp, HttpReply* reply)
{
	assert(acp);
	assert(reply);

	int flag = 0;
	int act = acp->action;
	struct header_info* hdr = acp->hdr;
	HttpHeaderEntry e;
	//HttpHeaderEntry *mye;
	int i;
	HttpHeaderEntry *myheader;
	HttpHeaderPos pos = HttpHeaderInitPos + HDR_ENUM_END;
	e.name = stringDup(&hdr->header);
	e.value = stringDup(&hdr->value);
	i = httpHeaderIdByNameDef(strBuf(hdr->header), strLen(hdr->header));
	e.id = i;
	if(i == -1)
	{
		e.id = HDR_OTHER;
		if(0 == act)
		{
			httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
		}
		else if(2 == act)
		{
			while ((myheader = httpHeaderGetEntryPlus(&reply->header, &pos))) 
			{
				if (myheader->id == HDR_OTHER && strCaseCmp(myheader->name, strBuf(hdr->header)) == 0)
				{
					debug(98, 3)("%s is myheader->value,%s is hdr->value\n",strBuf(myheader->value), strBuf(hdr->value));
					stringReset(&myheader->value, strBuf(hdr->value));

				}
			}
		}
		else if(1 == act)
		{
			httpHeaderDelByName(&reply->header,strBuf(hdr->header));
		}
		else if(3 == act)
		{
			while ((myheader = httpHeaderGetEntryPlus(&reply->header, &pos))) 
			{
				if (myheader->id == HDR_OTHER && strCaseCmp(myheader->name, strBuf(hdr->header)) == 0)
				{
					debug(98, 3)("%s is myheader->value,%s is hdr->value\n",strBuf(myheader->value), strBuf(hdr->value));
					flag = 1;
					stringReset(&myheader->value, strBuf(hdr->value));

				}
			}
			
			if(!flag)
				httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
		}
	}
	else
	{
		//mye = httpHeaderFindEntry2(&reply->header, i);
		//debug(98, 3) ("%d is i\n", i);

		if(0 == act)
		{
			httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
		}
		else if(2 == act)
		{
			if(httpHeaderDelByName(&reply->header,strBuf(hdr->header)))
			{
				httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
			}
			//mye = httpHeaderFindEntry2(&reply->header, i);
			//debug(98, 3)("%s is newvalue\n",strBuf(mye->value));
		}
		else if(1 == act)
		{
			httpHeaderDelByName(&reply->header,strBuf(hdr->header));
		}
		else if(3 == act)
		{
			httpHeaderDelByName(&reply->header,strBuf(hdr->header));
			httpHeaderAddEntry(&reply->header, httpHeaderEntryClone(&e));
		}
	}
	stringClean(&e.name);
	stringClean(&e.value);

	return 0;
}
Пример #18
0
int
httpHeaderParse(HttpHeader * hdr, const char *header_start, const char *header_end)
{
    const char *field_ptr = header_start;
    HttpHeaderEntry *e;

    assert(hdr);
    assert(header_start && header_end);
    debug(55, 7) ("parsing hdr: (%p)\n%s\n", hdr, getStringPrefix(header_start, header_end));
    HttpHeaderStats[hdr->owner].parsedCount++;
    if (memchr(header_start, '\0', header_end - header_start)) {
	debug(55, 1) ("WARNING: HTTP header contains NULL characters {%s}\n",
	    getStringPrefix(header_start, header_end));
	return httpHeaderReset(hdr);
    }
    /* common format headers are "<name>:[ws]<value>" lines delimited by <CRLF>.
     * continuation lines start with a (single) space or tab */
    while (field_ptr < header_end) {
	const char *field_start = field_ptr;
	const char *field_end;
	do {
	    const char *this_line = field_ptr;
	    field_ptr = memchr(field_ptr, '\n', header_end - field_ptr);
	    if (!field_ptr)
		return httpHeaderReset(hdr);	/* missing <LF> */
	    field_end = field_ptr;
	    field_ptr++;	/* Move to next line */
	    if (field_end > this_line && field_end[-1] == '\r') {
		field_end--;	/* Ignore CR LF */
		/* Ignore CR CR LF in relaxed mode */
		if (Config.onoff.relaxed_header_parser && field_end > this_line + 1 && field_end[-1] == '\r') {
		    debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
			("WARNING: Double CR characters in HTTP header {%s}\n", getStringPrefix(field_start, field_end));
		    field_end--;
		}
	    }
	    /* Barf on stray CR characters */
	    if (memchr(this_line, '\r', field_end - this_line)) {
		debug(55, 1) ("WARNING: suspicious CR characters in HTTP header {%s}\n",
		    getStringPrefix(field_start, field_end));
		if (Config.onoff.relaxed_header_parser) {
		    char *p = (char *) this_line;	/* XXX Warning! This destroys original header content and violates specifications somewhat */
		    while ((p = memchr(p, '\r', field_end - p)) != NULL)
			*p++ = ' ';
		} else
		    return httpHeaderReset(hdr);
	    }
	    if (this_line + 1 == field_end && this_line > field_start) {
		debug(55, 1) ("WARNING: Blank continuation line in HTTP header {%s}\n",
		    getStringPrefix(header_start, header_end));
		return httpHeaderReset(hdr);
	    }
	} while (field_ptr < header_end && (*field_ptr == ' ' || *field_ptr == '\t'));
	if (field_start == field_end) {
	    if (field_ptr < header_end) {
		debug(55, 1) ("WARNING: unparseable HTTP header field near {%s}\n",
		    getStringPrefix(field_start, header_end));
		return httpHeaderReset(hdr);
	    }
	    break;		/* terminating blank line */
	}
	e = httpHeaderEntryParseCreate(field_start, field_end);
	if (NULL == e) {
	    debug(55, 1) ("WARNING: unparseable HTTP header field {%s}\n",
		getStringPrefix(field_start, field_end));
	    debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
		(" in {%s}\n", getStringPrefix(header_start, header_end));
	    if (Config.onoff.relaxed_header_parser)
		continue;
	    else
		return httpHeaderReset(hdr);
	}
	if (e->id == HDR_CONTENT_LENGTH) {
	    squid_off_t l1;
	    HttpHeaderEntry *e2;
	    if (!httpHeaderParseSize(strBuf(e->value), &l1)) {
		debug(55, 1) ("WARNING: Unparseable content-length '%s'\n", strBuf(e->value));
		httpHeaderEntryDestroy(e);
		return httpHeaderReset(hdr);
	    }
	    e2 = httpHeaderFindEntry(hdr, e->id);
	    if (e2 && strCmp(e->value, strBuf(e2->value)) != 0) {
		squid_off_t 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(e2->value), &l2)) {
		    debug(55, 1) ("WARNING: Unparseable content-length '%s'\n", strBuf(e->value));
		    httpHeaderEntryDestroy(e);
		    return httpHeaderReset(hdr);
		}
		if (l1 > l2) {
		    httpHeaderDelById(hdr, e2->id);
		} else {
		    httpHeaderEntryDestroy(e);
		    continue;
		}
	    } else if (e2) {
		debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
		    ("NOTICE: found double content-length header\n");
		if (Config.onoff.relaxed_header_parser) {
		    httpHeaderEntryDestroy(e);
		    continue;
		} else {
		    httpHeaderEntryDestroy(e);
		    return httpHeaderReset(hdr);
		}
	    }
	}
	if (e->id == HDR_OTHER && stringHasWhitespace(strBuf(e->name))) {
	    debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
		("WARNING: found whitespace in HTTP header name {%s}\n", getStringPrefix(field_start, field_end));
	    if (!Config.onoff.relaxed_header_parser) {
		httpHeaderEntryDestroy(e);
		return httpHeaderReset(hdr);
	    }
	}
	httpHeaderAddEntry(hdr, e);
    }
    return 1;			/* even if no fields where found, it is a valid header */
}