]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: http-fetch: http_auth_bearer() must not match a missing header
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 23 Sep 2026 04:37:37 +0000 (04:37 +0000)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 23 Sep 2026 12:05:26 +0000 (14:05 +0200)
When http_auth_bearer() was called with a custom header name and this header
was not found, the fetch still succeeded and returned an empty string. So a
condition like "{ http_auth_bearer(x-tok) -m found }" was true for a request
without any such header.

Commit 909578520 ("BUG/MINOR: http-fetch: Fix http_auth_bearer() when custom
header is used") intended to report a mismatch in this case, as its message
says, but only did it for a header with a wrong type.

Let's return 0 when the header is not found. A reg-test is added for the
fetch with and without a custom header.

This should be backported as far as 2.6.

reg-tests/sample_fetches/http_auth_bearer.vtc [new file with mode: 0644]
src/http_fetch.c

diff --git a/reg-tests/sample_fetches/http_auth_bearer.vtc b/reg-tests/sample_fetches/http_auth_bearer.vtc
new file mode 100644 (file)
index 0000000..037c8ee
--- /dev/null
@@ -0,0 +1,57 @@
+varnishtest "http_auth_bearer() on the authorization header and on a custom one"
+
+# The fetch returns the token of a "Bearer" authorization, either from the
+# Authorization header or from the header given as argument. For the custom
+# header, the value must be the "Bearer" scheme followed by at least one
+# space and the token. When the custom header is absent, nothing is found,
+# so that the Authorization header is checked by the next rule.
+
+feature ignore_unknown_macro
+
+haproxy h1 -conf {
+    defaults
+        mode http
+        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"
+
+    frontend fe
+        bind "fd@${fe}"
+        http-request return status 200 hdr tok "%[http_auth_bearer(x-tok)]" if { http_auth_bearer(x-tok) -m found }
+        http-request return status 201 hdr tok "%[http_auth_bearer]" if { http_auth_bearer -m found }
+        http-request return status 404
+} -start
+
+client c1 -connect ${h1_fe_sock} {
+    # custom header, tokens of several lengths
+    txreq -hdr "x-tok: Bearer a"
+    rxresp
+    expect resp.status == 200
+    expect resp.http.tok == "a"
+
+    txreq -hdr "x-tok: Bearer abcdefg"
+    rxresp
+    expect resp.status == 200
+    expect resp.http.tok == "abcdefg"
+
+    # several spaces are allowed between the scheme and the token
+    txreq -hdr "x-tok: bearer   xyz123"
+    rxresp
+    expect resp.status == 200
+    expect resp.http.tok == "xyz123"
+
+    # another scheme
+    txreq -hdr "x-tok: Basic abcdef"
+    rxresp
+    expect resp.status == 404
+
+    # the Authorization header
+    txreq -hdr "authorization: Bearer abcdef"
+    rxresp
+    expect resp.status == 201
+    expect resp.http.tok == "abcdef"
+
+    txreq -hdr "authorization: Basic YTpi"
+    rxresp
+    expect resp.status == 404
+} -run
index 6133983c16a763e9e06bbf5583273cd2e7b95f36..f944925c949b3b014190506266d16bf4197d153c 100644 (file)
@@ -1486,6 +1486,8 @@ static int smp_fetch_http_auth_bearer(const struct arg *args, struct sample *smp
                        ctx.value = istskip(ctx.value, ' ');
                        chunk_initlen(&bearer_val, istptr(ctx.value), 0, istlen(ctx.value));
                }
+               else
+                       return 0;
        }
        else {
                txn = smp->strm->txn.http;