[BUG] http: trailing white spaces must also be trimmed after headers

Trailing spaces after headers were not trimmed, only the leading ones
were. An issue was detected today with a content-length value which
was padded with spaces and which was rejected. Recent updates to the
http-bis draft made it a lot more clear that such spaces must be ignored,
so this is what this patch does.

It should be backported to 1.4.
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 3f6724b..d9bf830 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -340,15 +340,18 @@
 };
 
 /* This structure is used by http_find_header() to return values of headers.
- * The header starts at <line>, the value at <line>+<val> for <vlen> bytes, and
- * sets <line>+<del> to point to the last delimitor (colon or comma) before
- * this value. <prev> points to the index of the header whose next is this one.
+ * The header starts at <line>, the value (excluding leading and trailing white
+ * spaces) at <line>+<val> for <vlen> bytes, followed by optional <tws> trailing
+ * white spaces, and sets <line>+<del> to point to the last delimitor (colon or
+ * comma) before this value. <prev> points to the index of the header whose next
+ * is this one.
  */
 struct hdr_ctx {
 	char *line;
 	int  idx;
-	int  val;  /* relative to line */
-	int  vlen; /* relative to line+val */
+	int  val;  /* relative to line, may skip some leading white spaces */
+	int  vlen; /* relative to line+val, stops before trailing white spaces */
+	int  tws;  /* added to vlen if some trailing white spaces are present */
 	int  del;  /* relative to line */
 	int  prev; /* index of previous header */
 };
diff --git a/src/proto_http.c b/src/proto_http.c
index 35c2f9d..a56be38 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -503,7 +503,7 @@
 		 * another one on the same line.
 		 */
 		sol = ctx->line;
-		ctx->del = ctx->val + ctx->vlen;
+		ctx->del = ctx->val + ctx->vlen + ctx->tws;
 		sov = sol + ctx->del;
 		eol = sol + idx->v[cur_idx].len;
 
@@ -551,6 +551,11 @@
 			ctx->val  = sov - sol;
 
 			eol = find_hdr_value_end(sov, eol);
+			ctx->tws = 0;
+			while (http_is_lws[(unsigned char)*(eol - 1)]) {
+				eol--;
+				ctx->tws++;
+			}
 			ctx->vlen = eol - sov;
 			return 1;
 		}
@@ -589,7 +594,7 @@
 		return 0;
 
 	hdr = &idx->v[cur_idx];
-	if (sol[ctx->del] == ':' && ctx->val + ctx->vlen == hdr->len) {
+	if (sol[ctx->del] == ':' && ctx->val + ctx->vlen + ctx->tws == hdr->len) {
 		/* This was the only value of the header, we must now remove it entirely. */
 		delta = buffer_replace2(buf, sol, sol + hdr->len + hdr->cr + 1, NULL, 0);
 		http_msg_move_end(msg, delta);
@@ -601,23 +606,23 @@
 		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->val = idx->v[ctx->idx].len; /* point to end of previous header */
-		ctx->vlen = 0;
+		ctx->tws = ctx->vlen = 0;
 		return ctx->idx;
 	}
 
 	/* This was not the only value of this header. We have to remove between
-	 * ctx->del+1 and ctx->val+ctx->vlen+1 included. If it is the last entry
-	 * of the list, we remove the last separator.
+	 * ctx->del+1 and ctx->val+ctx->vlen+ctx->tws+1 included. If it is the
+	 * last entry of the list, we remove the last separator.
 	 */
 
-	skip_comma = (ctx->val + ctx->vlen == hdr->len) ? 0 : 1;
+	skip_comma = (ctx->val + ctx->vlen + ctx->tws == hdr->len) ? 0 : 1;
 	delta = buffer_replace2(buf, sol + ctx->del + skip_comma,
-				sol + ctx->val + ctx->vlen + skip_comma,
+				sol + ctx->val + ctx->vlen + ctx->tws + skip_comma,
 				NULL, 0);
 	hdr->len += delta;
 	http_msg_move_end(msg, delta);
 	ctx->val = ctx->del;
-	ctx->vlen = 0;
+	ctx->tws = ctx->vlen = 0;
 	return ctx->idx;
 }