Skip to content

Commit f91c81e

Browse files
send_response: fix multi-valued response headers (#54)
Joining the values with a comma, like `get_headers(true)` does, is invalid for some headers, e.g. `Set-Cookie`. Instead, use `get_headers(false)` to have separate loop iterations for each value of the header. This way we have a separate `add_header()` call for each value, and let HAProxy take care of the rest. Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
1 parent 337733d commit f91c81e

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

auth-request.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function send_response(txn, response, hdr_fail)
9797
local reply = txn:reply()
9898
if response then
9999
reply:set_status(response.status_code)
100-
for header, value in response:get_headers(true) do
100+
for header, value in response:get_headers(false) do
101101
if header_match(header, hdr_fail) then
102102
reply:add_header(header, value)
103103
end

test/headers_fail_multiple.vtc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SPDX-License-Identifier: MIT
2+
3+
varnishtest "Verify that multi-valued filtered auth backend response headers are passed to the client."
4+
feature ignore_unknown_macro
5+
feature cmd "dpkg --compare-versions ${haproxy_version} ge 2.2"
6+
7+
server s_auth_backend {
8+
rxreq
9+
txresp \
10+
-status 401 \
11+
-hdr "x-user: admin" \
12+
-hdr "x-passwd: 123" \
13+
-hdr "x-reason: invalid pwd" \
14+
-hdr "x-reason: account expired" \
15+
-hdr "set-cookie: csrf=1234;" \
16+
-hdr "set-cookie: session=;" \
17+
-body "{\"msg\":\"invalid pwd\"}"
18+
} -start
19+
20+
haproxy h1 -conf {
21+
global
22+
lua-prepend-path ${testdir}/../?/http.lua
23+
lua-load ${testdir}/../auth-request.lua
24+
25+
listen fe1
26+
mode http
27+
bind "fd@${fe1}"
28+
29+
# VTest only sees the first header with a given name, thus
30+
# we split the expected headers into separate headers that
31+
# can be checked independently.
32+
http-response set-header set-cookie1 %[res.fhdr(set-cookie,1)]
33+
http-response set-header set-cookie2 %[res.fhdr(set-cookie,2)]
34+
http-response set-header x-reason1 %[res.fhdr(x-reason,1)]
35+
http-response set-header x-reason2 %[res.fhdr(x-reason,2)]
36+
37+
server be ${h1_fe2_addr}:${h1_fe2_port}
38+
39+
listen fe2
40+
mode http
41+
bind "fd@${fe2}"
42+
http-request lua.auth-intercept auth_backend / * * - x-user,x-reason,set-cookie
43+
44+
backend auth_backend
45+
mode http
46+
server auth_backend ${s_auth_backend_addr}:${s_auth_backend_port}
47+
} -start
48+
49+
client c1 -connect ${h1_fe1_sock} {
50+
txreq
51+
rxresp
52+
expect resp.status == 401
53+
expect resp.http.x-user == "admin"
54+
expect resp.http.x-passwd == "<undef>"
55+
56+
expect resp.http.x-reason !~ ","
57+
expect resp.http.x-reason1 == "invalid pwd"
58+
expect resp.http.x-reason2 == "account expired"
59+
60+
expect resp.http.set-cookie !~ ","
61+
expect resp.http.set-cookie1 == "csrf=1234;"
62+
expect resp.http.set-cookie2 == "session=;"
63+
64+
expect resp.body == "{\"msg\":\"invalid pwd\"}"
65+
} -run

0 commit comments

Comments
 (0)