From: Willy Tarreau Date: Wed, 7 Jan 2015 16:23:50 +0000 (+0100) Subject: BUG/MEDIUM: http: fix header removal when previous header ends with pure LF X-Git-Tag: v1.6-dev1~201 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7c1c21742639e57919b315fe02f6592c832be146;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: http: fix header removal when previous header ends with pure LF In 1.4-dev7, a header removal mechanism was introduced with commit 68085d8 ("[MINOR] http: add http_remove_header2() to remove a header value."). Due to a typo in the function, the beginning of the headers gets desynchronized if the header preceeding the deleted one ends with an LF/CRLF combination different form the one of the removed header. The reason is that while rewinding the pointer, we go back by a number of bytes taking into account the LF/CRLF status of the removed header instead of the previous one. The case where it fails is in http-request del-header/set-header where the multiple occurrences of a header are present and their LF/CRLF ending differs from the preceeding header. The loop then stops because no more headers are found given that the names and length do not match. Another point to take into consideration is that removing headers using a loop of http_find_header2() and this function is inefficient since we remove values one at a time while it could be simpler and faster to remove full header lines. This is something that should be addressed separately. This fix must be backported to 1.5 and 1.4. Note that http-send-name-header relies on this function as well so it could be possible that some of the issues encountered with it in 1.4 come from this bug. --- diff --git a/src/proto_http.c b/src/proto_http.c index b4861cea77..4b14b88fa8 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -731,7 +731,7 @@ int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ct if (idx->tail == ctx->idx) idx->tail = ctx->prev; ctx->idx = ctx->prev; /* walk back to the end of previous header */ - ctx->line -= idx->v[ctx->idx].len + idx->v[cur_idx].cr + 1; + ctx->line -= idx->v[ctx->idx].len + idx->v[ctx->idx].cr + 1; ctx->val = idx->v[ctx->idx].len; /* point to end of previous header */ ctx->tws = ctx->vlen = 0; return ctx->idx;