]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: http-fetch: do not count Set-Cookie attributes as cookies
authorWilly Tarreau <w@1wt.eu>
Wed, 30 Sep 2026 09:31:39 +0000 (11:31 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 30 Sep 2026 14:11:24 +0000 (16:11 +0200)
A Set-Cookie header contains a single cookie, and other elements on
the same line are not cookies but attributes (which can easily be
mistaken for them by a parser). That's what happens for res.cook_cnt()
which uses the same parser as req.cook_cnt() and counts apparent cookie
values without figuring it's parsing attributes. Let's just do like for
res.cookie_names() and check for a request or response before looping,
so that we can now count a single cookie per set-cookie response.

This can be backported to all stable versions.

src/http_fetch.c

index c7c967cb3b41d538394641dda66703f990d55661..af5dc3c07f4ffbf7095653566ea6a5f0818c06f0 100644 (file)
@@ -1844,6 +1844,7 @@ static int smp_fetch_cookie_cnt(const struct arg *args, struct sample *smp, cons
        char *val_beg, *val_end;
        char *cook = NULL;
        size_t cook_l = 0;
+       int is_req = !(check || (chn && chn->flags & CF_ISRESP));
        int cnt;
 
        if (args->type == ARGT_STR){
@@ -1854,7 +1855,7 @@ static int smp_fetch_cookie_cnt(const struct arg *args, struct sample *smp, cons
        if (!htx)
                return 0;
 
-       hdr = (!(check || (chn && chn->flags & CF_ISRESP)) ? ist("Cookie") : ist("Set-Cookie"));
+       hdr = (is_req ? ist("Cookie") : ist("Set-Cookie"));
 
        val_end = val_beg = NULL;
        ctx.blk = NULL;
@@ -1880,6 +1881,11 @@ static int smp_fetch_cookie_cnt(const struct arg *args, struct sample *smp, cons
                                                            &smp->data.u.str.area,
                                                            &smp->data.u.str.data))) {
                        cnt++;
+                       if (!is_req) {
+                               /* there's a single cookie per set-cookie header */
+                               val_beg = NULL;
+                               break;
+                       }
                }
        }