Skip to content

Commit 460266b

Browse files
tzssangglasssamugi
andauthored
[Backport release/0.8.x] fix(var): patch set_header (#100)
patch the req.set_header function to invalidate the relevant variable_index entry for the modified header. Specifically, after normalizing the header name, the corresponding variable_index entry is set to nil. This ensures that subsequent accesses to ngx.var.http_* variables will bypass the cached index and fetch the updated header value. same fix way as: #59 Fix: KAG-5963 Fix: FTI-6406 Signed-off-by: tzssangglass <[email protected]> Co-authored-by: Samuele <[email protected]>
1 parent d346692 commit 460266b

File tree

5 files changed

+167
-13
lines changed

5 files changed

+167
-13
lines changed

.github/workflows/tests.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
push:
66

77
env:
8-
KONG_VERSION: master
8+
KONG_VERSION: release/3.4.x
99
BUILD_ROOT: ${{ github.workspace }}/kong/bazel-bin/build
1010

1111
concurrency:
@@ -63,6 +63,22 @@ jobs:
6363
GH_TOKEN: ${{ github.token }}
6464
run: |
6565
cd kong
66+
67+
# Find the .rockspec file (handles varying filenames like kong-3.4.x-0.rockspec)
68+
ROCKSPEC_FILE=$(ls kong-*.rockspec | head -n 1)
69+
70+
# Check if the rockspec file exists
71+
if [[ -f "$ROCKSPEC_FILE" ]]; then
72+
echo "Modifying lua-messagepack version in $ROCKSPEC_FILE"
73+
74+
# Use sed to replace "lua-messagepack == 0.5.2" with "lua-messagepack == 0.5.4"
75+
sed -i 's/"lua-messagepack == 0\.5\.2"/"lua-messagepack == 0.5.4"/' "$ROCKSPEC_FILE"
76+
else
77+
echo "Error: .rockspec file not found!"
78+
exit 1
79+
fi
80+
81+
# Proceed with the build steps
6682
make build-kong
6783
make build-venv
6884
BUILD_PREFIX=$BUILD_ROOT/kong-dev

.luacheckrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ globals = {
2020
req = {
2121
set_uri_args = {
2222
read_only = false
23+
},
24+
set_header = {
25+
read_only = false
2326
}
2427
}
2528
}

lualib/resty/kong/var.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ local NGX_DECLINED = ngx.DECLINED
2424

2525
local variable_index = {}
2626
local metatable_patched
27+
local str_replace_char
28+
local replace_dashes_lower
2729

30+
local HTTP_PREFIX = "http_"
2831

2932
--Add back if stream module is implemented to aid readability
3033
--see bottom of: https://luajit.org/ext_ffi_tutorial.html
@@ -50,6 +53,11 @@ if subsystem == "http" then
5053
--ngx_lua_kong_ffi_var_get_by_index = C.ngx_http_lua_kong_ffi_var_get_by_index
5154
--ngx_lua_kong_ffi_var_set_by_index = C.ngx_http_lua_kong_ffi_var_set_by_index
5255
--ngx_lua_kong_ffi_var_load_indexes = C.ngx_http_lua_kong_ffi_var_load_indexes
56+
57+
str_replace_char = require("resty.core.utils").str_replace_char
58+
replace_dashes_lower = function(str)
59+
return str_replace_char(str:lower(), "-", "_")
60+
end
5361
end
5462

5563

@@ -158,6 +166,16 @@ local function patch_functions()
158166
variable_index.args = nil
159167
return orig_set_uri_args(...)
160168
end
169+
170+
local orig_set_header = req.set_header
171+
172+
req.set_header = function(name, value)
173+
local normalized_header = replace_dashes_lower(name)
174+
normalized_header = HTTP_PREFIX .. normalized_header
175+
variable_index[normalized_header] = nil
176+
177+
return orig_set_header(name, value)
178+
end
161179
end
162180

163181

t/005-indexed-var-openresty-suites.t

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use Test::Nginx::Socket::Lua;
99

1010
repeat_each(2);
1111

12-
plan tests => repeat_each() * (blocks() * 2 + 9 + 4 + 3);
12+
plan tests => repeat_each() * (blocks() * 2 + 9 + 4 + 3 + 3);
13+
1314

1415
#no_diff();
1516
#no_long_string();
@@ -387,3 +388,57 @@ foo=bar&added=yes
387388
[error]
388389
[crit]
389390
[alert]
391+
392+
393+
394+
=== TEST 14: patch metatable does not invalidate function req.set_header
395+
--- http_config
396+
lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;";
397+
lua_kong_load_var_index default;
398+
399+
init_by_lua_block {
400+
require("resty.kong.var").patch_metatable()
401+
}
402+
403+
--- config
404+
location /auth {
405+
content_by_lua_block {
406+
ngx.say(ngx.var.http_authorization)
407+
ngx.req.set_header("Authorization", "foo")
408+
ngx.say(ngx.var.http_authorization)
409+
ngx.req.set_header("Authorization", "bar")
410+
ngx.say(ngx.var.http_authorization)
411+
ngx.req.set_header("Authorization", "baz")
412+
ngx.say(ngx.var.http_authorization)
413+
ngx.req.set_header("Authorization", "qux")
414+
ngx.say(ngx.var.http_authorization)
415+
416+
ngx.say(ngx.var.http_kong_debug)
417+
ngx.req.set_header("Kong-Debug", "true")
418+
ngx.say(ngx.var.http_kong_debug)
419+
ngx.req.set_header("Kong-Debug", "false")
420+
ngx.say(ngx.var.http_kong_debug)
421+
ngx.req.set_header("Kong-Debug", "true")
422+
ngx.say(ngx.var.http_kong_debug)
423+
ngx.req.set_header("Kong-Debug", "false")
424+
ngx.say(ngx.var.http_kong_debug)
425+
}
426+
}
427+
428+
--- request
429+
GET /auth
430+
--- response_body
431+
nil
432+
foo
433+
bar
434+
baz
435+
qux
436+
nil
437+
true
438+
false
439+
true
440+
false
441+
--- no_error_log
442+
[error]
443+
[crit]
444+
[alert]

t/stream/001-upstream-tls.t

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,98 @@ run_tests();
1919
__DATA__
2020

2121
=== TEST 1: upstream TLS proxying works
22+
--- http_config
23+
lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;";
24+
25+
server {
26+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
27+
server_name example.com;
28+
ssl_certificate ../../cert/example.com.crt;
29+
ssl_certificate_key ../../cert/example.com.key;
30+
31+
server_tokens off;
32+
33+
location /foo {
34+
default_type 'text/plain';
35+
more_clear_headers Date;
36+
echo 'it works!';
37+
}
38+
}
39+
--- stream_config
40+
upstream foo {
41+
server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
42+
}
2243
--- stream_server_config
23-
proxy_pass mockbin.com:443;
44+
proxy_ssl_trusted_certificate ../../cert/ca.crt;
45+
proxy_ssl_verify on;
46+
proxy_ssl_name example.com;
2447
proxy_ssl on;
25-
proxy_ssl_server_name on;
48+
49+
proxy_pass foo;
50+
proxy_ssl_session_reuse off;
51+
2652
--- stream_request eval
27-
"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n"
28-
--- stream_response_like: ^HTTP/1.1 200 OK
53+
"GET /foo HTTP/1.0\r\nHost: example.com\r\n\r\n"
54+
55+
--- stream_response_like
56+
it works!
57+
2958
--- no_error_log
3059
[error]
3160

3261

3362

3463
=== TEST 2: upstream plaintext proxying works
64+
--- http_config
65+
lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;";
66+
67+
server {
68+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
69+
server_name example.com;
70+
71+
server_tokens off;
72+
73+
location /foo {
74+
default_type 'text/plain';
75+
more_clear_headers Date;
76+
echo 'it works!';
77+
}
78+
}
79+
--- stream_config
80+
upstream foo {
81+
server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
82+
}
3583
--- stream_server_config
36-
proxy_pass mockbin.com:80;
3784
proxy_ssl off;
85+
proxy_pass foo;
86+
3887
--- stream_request eval
39-
"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n"
40-
--- stream_response_like: ^HTTP/1.1 200 OK
88+
"GET /foo HTTP/1.0\r\nHost: example.com\r\n\r\n"
89+
90+
--- stream_response_like
91+
it works!
92+
4193
--- no_error_log
4294
[error]
4395

4496

4597

4698
=== TEST 3: upstream TLS proxying inhibit works
47-
--- stream_config
99+
--- http_config
48100
lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;";
49101

102+
server {
103+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
104+
server_name example.com;
105+
ssl_certificate ../../cert/example.com.crt;
106+
ssl_certificate_key ../../cert/example.com.key;
107+
108+
server_tokens off;
109+
}
110+
--- stream_config
111+
proxy_ssl_session_reuse off;
50112
--- stream_server_config
51-
proxy_pass mockbin.com:443;
113+
proxy_pass unix:$TEST_NGINX_HTML_DIR/nginx.sock;
52114
proxy_ssl on;
53115

54116
preread_by_lua_block {
@@ -57,7 +119,7 @@ __DATA__
57119
assert(tls.disable_proxy_ssl())
58120
}
59121
--- stream_request eval
60-
"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n"
122+
"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n"
61123
--- stream_response_like: ^.+400 The plain HTTP request was sent to HTTPS port.+$
62124
--- no_error_log
63125
[error]
@@ -99,7 +161,7 @@ __DATA__
99161
proxy_pass unix:$TEST_NGINX_HTML_DIR/nginx.sock;
100162

101163
--- stream_request eval
102-
"GET / HTTP/1.0\r\nHost: mockbin.com\r\n\r\n"
164+
"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n"
103165

104166
--- stream_response_like
105167
^.+No required SSL certificate was sent.+

0 commit comments

Comments
 (0)