]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: Log warning if (add|set)-header fails
authorTim Duesterhus <tim@bastelstu.be>
Sun, 27 May 2018 18:35:08 +0000 (20:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 28 May 2018 12:53:59 +0000 (14:53 +0200)
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.

include/types/counters.h
include/types/stats.h
src/proto_http.c
src/stats.c

index 06ce617280d1d5d327fb19add05a76069c29d344..fd83ebbe7f3086d95ff39a8552435cbabd852632 100644 (file)
@@ -44,6 +44,7 @@ struct fe_counters {
        long long failed_req;                   /* failed requests (eg: invalid or timeout) */
        long long denied_conn;                  /* denied connection requests (tcp-req-conn rules) */
        long long denied_sess;                  /* denied session requests (tcp-req-sess rules) */
+       long long failed_rewrites;              /* failed rewrites (warning) */
 
        long long cli_aborts;                   /* aborted responses during DATA phase caused by the client */
        long long srv_aborts;                   /* aborted responses during DATA phase caused by the server */
@@ -88,6 +89,7 @@ struct be_counters {
        long long srv_aborts;                   /* aborted responses during DATA phase caused by the server */
        long long retries;                      /* retried and redispatched connections (BE only) */
        long long redispatches;                 /* retried and redispatched connections (BE only) */
+       long long failed_rewrites;              /* failed rewrites (warning) */
        long long failed_secu;                  /* blocked responses because of security concerns */
 
        long long failed_checks, failed_hana;   /* failed health checks and health analyses for servers */
index b4124334aa46b272aea2772499faebe15c183465..a22be365e3cfa10b1bbac7d6aa0ae32a48d8a2fb 100644 (file)
@@ -383,6 +383,7 @@ enum stat_field {
        ST_F_INTERCEPTED,
        ST_F_DCON,
        ST_F_DSES,
+       ST_F_WREW,
 
        /* must always be the last one */
        ST_F_TOTAL_FIELDS
index efa6d6a36930f3f4636a83c0c1ae0a0b41868631..4fd5aeb156bc51b74e30043365e9b51499ee67f3 100644 (file)
@@ -2631,7 +2631,20 @@ resume_execution:
                                }
                        }
 
-                       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 @@ resume_execution:
                                        http_remove_header2(&txn->rsp, &txn->hdr_idx, &ctx);
                                }
                        }
-                       http_header_add_tail2(&txn->rsp, &txn->hdr_idx, replace->str, replace->len);
+
+                       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);
+                       }
 
                        free_trash_chunk(replace);
                        break;
index 7ad30a178f51c05cc7051945330f5554e60e0dff..6255ce3d6bf712bb1872b78e714a000220790455 100644 (file)
@@ -216,6 +216,7 @@ const char *stat_field_names[ST_F_TOTAL_FIELDS] = {
        [ST_F_INTERCEPTED]    = "intercepted",
        [ST_F_DCON]           = "dcon",
        [ST_F_DSES]           = "dses",
+       [ST_F_WREW]           = "wrew",
 };
 
 /* one line of info */
@@ -1298,6 +1299,7 @@ int stats_fill_fe_stats(struct proxy *px, struct field *stats, int len)
        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 @@ int stats_fill_li_stats(struct proxy *px, struct listener *l, int flags,
        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 @@ int stats_fill_sv_stats(struct proxy *px, struct server *sv, int flags,
        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 @@ int stats_fill_be_stats(struct proxy *px, int flags, struct field *stats, int le
        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);