MINOR: http: Log warning if (add|set)-header fails

This patch adds a warning if an http-(request|reponse) (add|set)-header
rewrite fails to change the respective header in a request or response.

This usually happens when tune.maxrewrite is not sufficient to hold all
the headers that should be added.
diff --git a/src/proto_http.c b/src/proto_http.c
index efa6d6a..4fd5aeb 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2631,7 +2631,20 @@
 				}
 			}
 
-			http_header_add_tail2(&txn->req, &txn->hdr_idx, replace->str, replace->len);
+			if (http_header_add_tail2(&txn->req, &txn->hdr_idx, replace->str, replace->len) < 0) {
+				static unsigned char rate_limit = 0;
+
+				if ((rate_limit++ & 255) == 0) {
+					replace->str[rule->arg.hdr_add.name_len] = 0;
+					send_log(px, LOG_WARNING, "Proxy %s failed to add or set the request header '%s' for request #%u. You might need to increase tune.maxrewrite.", px->id, replace->str, s->uniq_id);
+				}
+
+				HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
+				if (sess->fe != s->be)
+					HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
+				if (sess->listener->counters)
+					HA_ATOMIC_ADD(&sess->listener->counters->failed_rewrites, 1);
+			}
 
 			free_trash_chunk(replace);
 			break;
@@ -2931,7 +2944,23 @@
 					http_remove_header2(&txn->rsp, &txn->hdr_idx, &ctx);
 				}
 			}
+
+			if (http_header_add_tail2(&txn->rsp, &txn->hdr_idx, replace->str, replace->len) < 0) {
+				static unsigned char rate_limit = 0;
+
+				if ((rate_limit++ & 255) == 0) {
+					replace->str[rule->arg.hdr_add.name_len] = 0;
+					send_log(px, LOG_WARNING, "Proxy %s failed to add or set the response header '%s' for request #%u. You might need to increase tune.maxrewrite.", px->id, replace->str, s->uniq_id);
+				}
+
+				HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
+				if (sess->fe != s->be)
+					HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
+				if (sess->listener->counters)
+					HA_ATOMIC_ADD(&sess->listener->counters->failed_rewrites, 1);
+				if (objt_server(s->target))
+					HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_rewrites, 1);
+			}
-			http_header_add_tail2(&txn->rsp, &txn->hdr_idx, replace->str, replace->len);
 
 			free_trash_chunk(replace);
 			break;
diff --git a/src/stats.c b/src/stats.c
index 7ad30a1..6255ce3 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -216,6 +216,7 @@
 	[ST_F_INTERCEPTED]    = "intercepted",
 	[ST_F_DCON]           = "dcon",
 	[ST_F_DSES]           = "dses",
+	[ST_F_WREW]           = "wrew",
 };
 
 /* one line of info */
@@ -1298,6 +1299,7 @@
 	stats[ST_F_RATE]     = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_sess_per_sec));
 	stats[ST_F_RATE_LIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->fe_sps_lim);
 	stats[ST_F_RATE_MAX] = mkf_u32(FN_MAX, px->fe_counters.sps_max);
+	stats[ST_F_WREW]     = mkf_u64(FN_COUNTER, px->fe_counters.failed_rewrites);
 
 	/* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
 	if (px->mode == PR_MODE_HTTP) {
@@ -1388,6 +1390,7 @@
 	stats[ST_F_IID]      = mkf_u32(FO_KEY|FS_SERVICE, px->uuid);
 	stats[ST_F_SID]      = mkf_u32(FO_KEY|FS_SERVICE, l->luid);
 	stats[ST_F_TYPE]     = mkf_u32(FO_CONFIG|FS_SERVICE, STATS_TYPE_SO);
+	stats[ST_F_WREW]     = mkf_u64(FN_COUNTER, l->counters->failed_rewrites);
 
 	if (flags & ST_SHLGNDS) {
 		char str[INET6_ADDRSTRLEN];
@@ -1553,6 +1556,7 @@
 	stats[ST_F_ERESP]    = mkf_u64(FN_COUNTER, sv->counters.failed_resp);
 	stats[ST_F_WRETR]    = mkf_u64(FN_COUNTER, sv->counters.retries);
 	stats[ST_F_WREDIS]   = mkf_u64(FN_COUNTER, sv->counters.redispatches);
+	stats[ST_F_WREW]     = mkf_u64(FN_COUNTER, sv->counters.failed_rewrites);
 
 	/* status */
 	fld_status = chunk_newstr(out);
@@ -1745,6 +1749,7 @@
 	stats[ST_F_ERESP]    = mkf_u64(FN_COUNTER, px->be_counters.failed_resp);
 	stats[ST_F_WRETR]    = mkf_u64(FN_COUNTER, px->be_counters.retries);
 	stats[ST_F_WREDIS]   = mkf_u64(FN_COUNTER, px->be_counters.redispatches);
+	stats[ST_F_WREW]     = mkf_u64(FN_COUNTER, px->be_counters.failed_rewrites);
 	stats[ST_F_STATUS]   = mkf_str(FO_STATUS, (px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN");
 	stats[ST_F_WEIGHT]   = mkf_u32(FN_AVG, (px->lbprm.tot_weight * px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv);
 	stats[ST_F_ACT]      = mkf_u32(0, px->srv_act);