[RELEASE] Released version 1.5.12 Released version 1.5.12 with the following main changes : - BUG/MINOR: ssl: Display correct filename in error message - DOC: Fix L4TOUT typo in documentation - BUG/MEDIUM: Do not consider an agent check as failed on L7 error - BUG/MINOR: pattern: error message missing - BUG/MEDIUM: pattern: some entries are not deleted with case insensitive match - BUG/MEDIUM: buffer: one byte miss in buffer free space check - BUG/MAJOR: http: don't read past buffer's end in http_replace_value - BUG/MEDIUM: http: the function "(req|res)-replace-value" doesn't respect the HTTP syntax - BUG/MEDIUM: peers: correctly configure the client timeout - BUG/MINOR: compression: consider the expansion factor in init - BUG/MEDIUM: http: hdr_cnt would not count any header when called without name - BUG/MEDIUM: listener: don't report an error when resuming unbound listeners - BUG/MEDIUM: init: don't limit cpu-map to the first 32 processes only - BUG/MEDIUM: stream-int: always reset si->ops when si->end is nullified - BUG/MEDIUM: http: remove content-length from chunked messages - DOC: http: update the comments about the rules for determining transfer-length - BUG/MEDIUM: http: do not restrict parsing of transfer-encoding to HTTP/1.1 - BUG/MEDIUM: http: incorrect transfer-coding in the request is a bad request - BUG/MEDIUM: http: remove content-length form responses with bad transfer-encoding - MEDIUM: http: restrict the HTTP version token to 1 digit as per RFC7230 - MEDIUM: http: add option-ignore-probes to get rid of the floods of 408 - BUG/MINOR: config: clear proxy->table.peers.p for disabled proxies - MINOR: stick-table: don't attach to peers in stopped state - MEDIUM: config: initialize stick-tables after peers, not before - MEDIUM: peers: add the ability to disable a peers section - DOC: document option http-ignore-probes - DOC: fix the comments about the meaning of msg->sol in HTTP - BUG/MEDIUM: http: wait for the exact amount of body bytes in wait_for_request_body - BUG/MAJOR: http: prevent risk of reading past end with balance url_param - DOC: update the doc on the proxy protocol Signed-off-by: heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -1,30 +0,0 @@ | |||
From e338a8741983acc9a4501a03ecd593d89e6fade3 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <tfournier@exceliance.fr> | |||
Date: Fri, 6 Feb 2015 17:50:55 +0100 | |||
Subject: [PATCH 1/2] BUG/MINOR: pattern: error message missing | |||
This patch must be backported in 1.5 version. | |||
(cherry picked from commit 8aa8384e22dd0b66ded00c70a9c6034278b4bb69) | |||
--- | |||
src/pattern.c | 4 +++- | |||
1 file changed, 3 insertions(+), 1 deletion(-) | |||
diff --git a/src/pattern.c b/src/pattern.c | |||
index 208e33a..a6fc52d 100644 | |||
--- a/src/pattern.c | |||
+++ b/src/pattern.c | |||
@@ -989,8 +989,10 @@ int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err) | |||
/* allocate pattern */ | |||
patl = calloc(1, sizeof(*patl)); | |||
- if (!patl) | |||
+ if (!patl) { | |||
+ memprintf(err, "out of memory while indexing pattern"); | |||
return 0; | |||
+ } | |||
/* duplicate pattern */ | |||
memcpy(&patl->pat, pat, sizeof(*pat)); | |||
-- | |||
2.0.4 | |||
@ -1,38 +0,0 @@ | |||
From 623401b983185c1e0f6507e96557de3bc46fd41b Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <tfournier@exceliance.fr> | |||
Date: Fri, 6 Feb 2015 17:53:54 +0100 | |||
Subject: [PATCH 2/2] BUG/MEDIUM: pattern: some entries are not deleted with | |||
case insensitive match | |||
ACL or map entries are not deleted with the command "del acl" or "del map" | |||
if the case insentive flag is set. | |||
This is because the the case insensitive string are stored in a list and the | |||
default delete function associated with string looks in a tree. I add a check | |||
of the case insensitive flag and execute the delete function for lists if it | |||
is set. | |||
This patch must be backported in 1.5 version. | |||
(cherry picked from commit 73bc285be194f443dc7eab9c949e87e1dbe8f70c) | |||
--- | |||
src/pattern.c | 4 ++++ | |||
1 file changed, 4 insertions(+) | |||
diff --git a/src/pattern.c b/src/pattern.c | |||
index a6fc52d..b19ffe2 100644 | |||
--- a/src/pattern.c | |||
+++ b/src/pattern.c | |||
@@ -1308,6 +1308,10 @@ void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref) | |||
struct ebmb_node *node, *next_node; | |||
struct pattern_tree *elt; | |||
+ /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */ | |||
+ if (expr->mflags & PAT_MF_IGNORE_CASE) | |||
+ return pat_del_list_ptr(expr, ref); | |||
+ | |||
/* browse each node of the tree. */ | |||
for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL; | |||
node; | |||
-- | |||
2.0.4 | |||
@ -1,43 +0,0 @@ | |||
From bfb8f885955efa1ef90f79595f16a01e30fd0dcf Mon Sep 17 00:00:00 2001 | |||
From: Simon Horman <horms@verge.net.au> | |||
Date: Thu, 26 Feb 2015 11:26:17 +0900 | |||
Subject: [PATCH 3/9] BUG/MEDIUM: Do not consider an agent check as failed on | |||
L7 error | |||
As failure to connect to the agent check is not sufficient to mark it as | |||
failed it stands to reason that an L7 error shouldn't either. | |||
Without this fix if an L7 error occurs, for example of connectivity to the | |||
agent is lost immediately after establishing a connection to it, then the | |||
agent check will be considered to have failed and thus may end up with zero | |||
health. Once this has occurred if the primary health check also reaches | |||
zero health, which is likely if connectivity to the server is lost, then | |||
the server will be marked as down and not be marked as up again until a | |||
successful agent check occurs regardless of the success of any primary | |||
health checks. | |||
This behaviour is not correct as a failed agent check should never cause a | |||
server to be marked as down or by extension continue to be marked as down. | |||
Signed-off-by: Simon Horman <horms@verge.net.au> | |||
(cherry picked from commit eaabd52e29a29187f9829fe727028a6ca530cbf9) | |||
--- | |||
src/checks.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/checks.c b/src/checks.c | |||
index b9048da..71debb6 100644 | |||
--- a/src/checks.c | |||
+++ b/src/checks.c | |||
@@ -246,7 +246,7 @@ static void set_server_check_status(struct check *check, short status, const cha | |||
* cause the server to be marked down. | |||
*/ | |||
if ((!(check->state & CHK_ST_AGENT) || | |||
- (check->status >= HCHK_STATUS_L7TOUT)) && | |||
+ (check->status >= HCHK_STATUS_L57DATA)) && | |||
(check->health >= check->rise)) { | |||
s->counters.failed_checks++; | |||
report = 1; | |||
-- | |||
2.0.5 | |||
@ -1,33 +0,0 @@ | |||
From fc940eb2bf0bbd7adf5b283f28bcff136501ae7f Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Fri, 13 Mar 2015 16:18:25 +0100 | |||
Subject: [PATCH 4/9] BUG/MEDIUM: peers: correctly configure the client timeout | |||
The peers frontend timeout was mistakenly set on timeout.connect instead | |||
of timeout.client, resulting in no timeout being applied to the peers | |||
connections. The impact is just that peers can establish connections and | |||
remain connected until they speak. Once they start speaking, only one of | |||
them will still be accepted, and old sessions will be killed, so the | |||
problem is limited. This fix should however be backported to 1.5 since | |||
it was introduced in 1.5-dev3 with peers. | |||
(cherry picked from commit 9ff95bb18c4cd9ae747fa5b3bef6d3f94e54172f) | |||
--- | |||
src/cfgparse.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||
index a91e027..b7613b8 100644 | |||
--- a/src/cfgparse.c | |||
+++ b/src/cfgparse.c | |||
@@ -1834,7 +1834,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) | |||
curpeers->peers_fe->cap = PR_CAP_FE; | |||
curpeers->peers_fe->maxconn = 0; | |||
curpeers->peers_fe->conn_retries = CONN_RETRIES; | |||
- curpeers->peers_fe->timeout.connect = 5000; | |||
+ curpeers->peers_fe->timeout.client = MS_TO_TICKS(5000); | |||
curpeers->peers_fe->accept = peer_accept; | |||
curpeers->peers_fe->options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON | PR_O2_SMARTACC; | |||
curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file); | |||
-- | |||
2.0.5 | |||
@ -1,30 +0,0 @@ | |||
From b92902814f796bb1dc24bab2179000caceb5b151 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <tfournier@exceliance.fr> | |||
Date: Tue, 10 Mar 2015 01:55:01 +0100 | |||
Subject: [PATCH 5/9] BUG/MEDIUM: buffer: one byte miss in buffer free space | |||
check | |||
Space is not avalaible only if the end of the data inserted | |||
is strictly greater than the end of buffer. If these two value | |||
are equal, the space is avamaible. | |||
(cherry picked from commit fdda6777bffb4f933569c609ba54e24ea5eabf29) | |||
--- | |||
src/buffer.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/buffer.c b/src/buffer.c | |||
index 9037dd3..8d2644e 100644 | |||
--- a/src/buffer.c | |||
+++ b/src/buffer.c | |||
@@ -46,7 +46,7 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int | |||
delta = len - (end - pos); | |||
- if (bi_end(b) + delta >= b->data + b->size) | |||
+ if (bi_end(b) + delta > b->data + b->size) | |||
return 0; /* no space left */ | |||
if (buffer_not_empty(b) && | |||
-- | |||
2.0.5 | |||
@ -1,52 +0,0 @@ | |||
From 8e05ac2044c6523c867ceaaae1f10486370eec89 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <tfournier@haproxy.com> | |||
Date: Mon, 16 Mar 2015 11:14:41 +0100 | |||
Subject: [PATCH 6/9] BUG/MAJOR: http: don't read past buffer's end in | |||
http_replace_value | |||
The function http_replace_value use bad variable to detect the end | |||
of the input string. | |||
Regression introduced by the patch "MEDIUM: regex: Remove null | |||
terminated strings." (c9c2daf2) | |||
We need to backport this patch int the 1.5 stable branch. | |||
WT: there is no possibility to overwrite existing data as we only read | |||
past the end of the request buffer, to copy into the trash. The copy | |||
is bounded by buffer_replace2(), just like the replacement performed | |||
by exp_replace(). However if a buffer happens to contain non-zero data | |||
up to the next unmapped page boundary, there's a theorical risk of | |||
crashing the process despite this not being reproducible in tests. | |||
The risk is low because "http-request replace-value" did not work due | |||
to this bug so that probably means it's not used yet. | |||
(cherry picked from commit 534101658d6e19aeb598bf7833a8ce167498c4ed) | |||
--- | |||
src/proto_http.c | 4 ++-- | |||
1 file changed, 2 insertions(+), 2 deletions(-) | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index 705f3b4..f53b5e2 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -3206,7 +3206,7 @@ static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, cha | |||
/* look for delim. */ | |||
p_delim = p; | |||
- while (p_delim < p + len && *p_delim != delim) | |||
+ while (p_delim < val + len && *p_delim != delim) | |||
p_delim++; | |||
if (regex_exec_match2(re, p, p_delim-p, MAX_MATCH, pmatch)) { | |||
@@ -3230,7 +3230,7 @@ static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, cha | |||
return -1; | |||
/* end of the replacements. */ | |||
- if (p_delim >= p + len) | |||
+ if (p_delim >= val + len) | |||
break; | |||
/* Next part. */ | |||
-- | |||
2.0.5 | |||
@ -1,171 +0,0 @@ | |||
From 06170c50ae5cd0fb23510b832826f7e63a5a8894 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <tfournier@haproxy.com> | |||
Date: Mon, 16 Mar 2015 23:23:53 +0100 | |||
Subject: [PATCH 7/9] BUG/MEDIUM: http: the function "(req|res)-replace-value" | |||
doesn't respect the HTTP syntax | |||
These function used an invalid header parser. | |||
- The trailing white-spaces were embedded in the replacement regex, | |||
- The double-quote (") containing comma (,) were not respected. | |||
This patch replace this parser by the "official" parser http_find_header2(). | |||
(cherry picked from commit 191f9efdc58f21af1d9dde3db5ba198d7f1ce22e) | |||
--- | |||
src/proto_http.c | 126 +++++++++++++++---------------------------------------- | |||
1 file changed, 34 insertions(+), 92 deletions(-) | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index f53b5e2..c49c4f4 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -3179,113 +3179,55 @@ static inline void inet_set_tos(int fd, struct sockaddr_storage from, int tos) | |||
#endif | |||
} | |||
-/* Returns the number of characters written to destination, | |||
- * -1 on internal error and -2 if no replacement took place. | |||
- */ | |||
-static int http_replace_header(struct my_regex *re, char *dst, uint dst_size, char *val, int len, | |||
- const char *rep_str) | |||
-{ | |||
- if (!regex_exec_match2(re, val, len, MAX_MATCH, pmatch)) | |||
- return -2; | |||
- | |||
- return exp_replace(dst, dst_size, val, rep_str, pmatch); | |||
-} | |||
- | |||
-/* Returns the number of characters written to destination, | |||
- * -1 on internal error and -2 if no replacement took place. | |||
- */ | |||
-static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, char *val, int len, char delim, | |||
- const char *rep_str) | |||
-{ | |||
- char* p = val; | |||
- char* dst_end = dst + dst_size; | |||
- char* dst_p = dst; | |||
- | |||
- for (;;) { | |||
- char *p_delim; | |||
- | |||
- /* look for delim. */ | |||
- p_delim = p; | |||
- while (p_delim < val + len && *p_delim != delim) | |||
- p_delim++; | |||
- | |||
- if (regex_exec_match2(re, p, p_delim-p, MAX_MATCH, pmatch)) { | |||
- int replace_n = exp_replace(dst_p, dst_end - dst_p, p, rep_str, pmatch); | |||
- | |||
- if (replace_n < 0) | |||
- return -1; | |||
- | |||
- dst_p += replace_n; | |||
- } else { | |||
- uint len = p_delim - p; | |||
- | |||
- if (dst_p + len >= dst_end) | |||
- return -1; | |||
- | |||
- memcpy(dst_p, p, len); | |||
- dst_p += len; | |||
- } | |||
- | |||
- if (dst_p >= dst_end) | |||
- return -1; | |||
- | |||
- /* end of the replacements. */ | |||
- if (p_delim >= val + len) | |||
- break; | |||
- | |||
- /* Next part. */ | |||
- *dst_p++ = delim; | |||
- p = p_delim + 1; | |||
- } | |||
- | |||
- return dst_p - dst; | |||
-} | |||
- | |||
static int http_transform_header(struct session* s, struct http_msg *msg, const char* name, uint name_len, | |||
char* buf, struct hdr_idx* idx, struct list *fmt, struct my_regex *re, | |||
struct hdr_ctx* ctx, int action) | |||
{ | |||
+ int (*http_find_hdr_func)(const char *name, int len, char *sol, | |||
+ struct hdr_idx *idx, struct hdr_ctx *ctx); | |||
+ struct chunk *replace = get_trash_chunk(); | |||
+ struct chunk *output = get_trash_chunk(); | |||
+ | |||
+ replace->len = build_logline(s, replace->str, replace->size, fmt); | |||
+ if (replace->len >= replace->size - 1) | |||
+ return -1; | |||
+ | |||
ctx->idx = 0; | |||
- while (http_find_full_header2(name, name_len, buf, idx, ctx)) { | |||
+ /* Choose the header browsing function. */ | |||
+ switch (action) { | |||
+ case HTTP_REQ_ACT_REPLACE_VAL: | |||
+ case HTTP_RES_ACT_REPLACE_VAL: | |||
+ http_find_hdr_func = http_find_header2; | |||
+ break; | |||
+ case HTTP_REQ_ACT_REPLACE_HDR: | |||
+ case HTTP_RES_ACT_REPLACE_HDR: | |||
+ http_find_hdr_func = http_find_full_header2; | |||
+ break; | |||
+ default: /* impossible */ | |||
+ return -1; | |||
+ } | |||
+ | |||
+ while (http_find_hdr_func(name, name_len, buf, idx, ctx)) { | |||
struct hdr_idx_elem *hdr = idx->v + ctx->idx; | |||
int delta; | |||
- char* val = (char*)ctx->line + ctx->val; | |||
- char* val_end = (char*)ctx->line + hdr->len; | |||
- char* reg_dst_buf; | |||
- uint reg_dst_buf_size; | |||
- int n_replaced; | |||
- | |||
- trash.len = build_logline(s, trash.str, trash.size, fmt); | |||
- | |||
- if (trash.len >= trash.size - 1) | |||
- return -1; | |||
+ char *val = ctx->line + ctx->val; | |||
+ char* val_end = val + ctx->vlen; | |||
- reg_dst_buf = trash.str + trash.len + 1; | |||
- reg_dst_buf_size = trash.size - trash.len - 1; | |||
+ if (!regex_exec_match2(re, val, val_end-val, MAX_MATCH, pmatch)) | |||
+ continue; | |||
- switch (action) { | |||
- case HTTP_REQ_ACT_REPLACE_VAL: | |||
- case HTTP_RES_ACT_REPLACE_VAL: | |||
- n_replaced = http_replace_value(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, ',', trash.str); | |||
- break; | |||
- case HTTP_REQ_ACT_REPLACE_HDR: | |||
- case HTTP_RES_ACT_REPLACE_HDR: | |||
- n_replaced = http_replace_header(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, trash.str); | |||
- break; | |||
- default: /* impossible */ | |||
+ output->len = exp_replace(output->str, output->size, val, replace->str, pmatch); | |||
+ if (output->len == -1) | |||
return -1; | |||
- } | |||
- switch (n_replaced) { | |||
- case -1: return -1; | |||
- case -2: continue; | |||
- } | |||
- | |||
- delta = buffer_replace2(msg->chn->buf, val, val_end, reg_dst_buf, n_replaced); | |||
+ delta = buffer_replace2(msg->chn->buf, val, val_end, output->str, output->len); | |||
hdr->len += delta; | |||
http_msg_move_end(msg, delta); | |||
+ | |||
+ /* Adjust the length of the current value of the index. */ | |||
+ ctx->vlen += delta; | |||
} | |||
return 0; | |||
-- | |||
2.0.5 | |||
@ -1,43 +0,0 @@ | |||
From 9b9531d90dfd8a334958d23394afafd0185bfa21 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Sat, 28 Mar 2015 12:20:33 +0100 | |||
Subject: [PATCH 8/9] BUG/MINOR: compression: consider the expansion factor in | |||
init | |||
When checking if the buffer is large enough, we used to rely on a fixed | |||
size that was "apparently" enough. We need to consider the expansion | |||
factor of deflate-encoded streams instead, which is of 5 bytes per 32kB. | |||
The previous value was OK till 128kB buffers but became wrong past that. | |||
It's totally harmless since we always keep the reserve when compressiong, | |||
so there's 1kB or so available, which is enough for buffers as large as | |||
6.5 MB, but better fix the check anyway. | |||
This fix could be backported into 1.5 since compression was added there. | |||
(cherry picked from commit 2aee2215c908c6997addcd1714b5b10f73c0703d) | |||
--- | |||
src/compression.c | 9 ++++++--- | |||
1 file changed, 6 insertions(+), 3 deletions(-) | |||
diff --git a/src/compression.c b/src/compression.c | |||
index 3d6085e..d55f14e 100644 | |||
--- a/src/compression.c | |||
+++ b/src/compression.c | |||
@@ -130,9 +130,12 @@ int http_compression_buffer_init(struct session *s, struct buffer *in, struct bu | |||
{ | |||
int left; | |||
- /* not enough space */ | |||
- if (in->size - buffer_len(in) < 40) | |||
- return -1; | |||
+ /* output stream requires at least 10 bytes for the gzip header, plus | |||
+ * at least 8 bytes for the gzip trailer (crc+len), plus a possible | |||
+ * plus at most 5 bytes per 32kB block and 2 bytes to close the stream. | |||
+ */ | |||
+ if (in->size - buffer_len(in) < 20 + 5 * ((in->i + 32767) >> 15)) | |||
+ return -1; | |||
/* We start by copying the current buffer's pending outgoing data into | |||
* a new temporary buffer that we initialize with a new empty chunk. | |||
-- | |||
2.0.5 | |||
@ -1,70 +0,0 @@ | |||
From 2943734024525d4b9aeec13cca2c1d230c358ee5 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Wed, 1 Apr 2015 19:16:09 +0200 | |||
Subject: [PATCH 9/9] BUG/MEDIUM: http: hdr_cnt would not count any header when | |||
called without name | |||
It's documented that these sample fetch functions should count all headers | |||
and/or all values when called with no name but in practice it's not what is | |||
being done as a missing name causes an immediate return and an absence of | |||
result. | |||
This bug is present in 1.5 as well and must be backported. | |||
(cherry picked from commit 601a4d1741100d7a861b6d9b66561335c9911277) | |||
--- | |||
src/proto_http.c | 20 ++++++++++++++------ | |||
1 file changed, 14 insertions(+), 6 deletions(-) | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index c49c4f4..ccd52ad 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -10014,15 +10014,19 @@ smp_fetch_fhdr_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int | |||
struct hdr_ctx ctx; | |||
const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp; | |||
int cnt; | |||
+ const char *name = NULL; | |||
+ int len = 0; | |||
- if (!args || args->type != ARGT_STR) | |||
- return 0; | |||
+ if (args && args->type == ARGT_STR) { | |||
+ name = args->data.str.str; | |||
+ len = args->data.str.len; | |||
+ } | |||
CHECK_HTTP_MESSAGE_FIRST(); | |||
ctx.idx = 0; | |||
cnt = 0; | |||
- while (http_find_full_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx)) | |||
+ while (http_find_full_header2(name, len, msg->chn->buf->p, idx, &ctx)) | |||
cnt++; | |||
smp->type = SMP_T_UINT; | |||
@@ -10101,15 +10105,19 @@ smp_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int o | |||
struct hdr_ctx ctx; | |||
const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp; | |||
int cnt; | |||
+ const char *name = NULL; | |||
+ int len = 0; | |||
- if (!args || args->type != ARGT_STR) | |||
- return 0; | |||
+ if (args && args->type == ARGT_STR) { | |||
+ name = args->data.str.str; | |||
+ len = args->data.str.len; | |||
+ } | |||
CHECK_HTTP_MESSAGE_FIRST(); | |||
ctx.idx = 0; | |||
cnt = 0; | |||
- while (http_find_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx)) | |||
+ while (http_find_header2(name, len, msg->chn->buf->p, idx, &ctx)) | |||
cnt++; | |||
smp->type = SMP_T_UINT; | |||
-- | |||
2.0.5 | |||