Skip to content

Commit 55b9e12

Browse files
ddragosdselfxp
authored andcommitted
cjson.decode should be wrapped in a pcall (#10)
* Added a test to prove #9 * added a try/catch to cjson.decode
1 parent 580bca1 commit 55b9e12

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

src/lua/api-gateway/tracking/RequestTrackingManager.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,28 +157,30 @@ function _M:getRulesForType(rule_type)
157157
-- 0. check if lastModifiedDate for the dict matches the local date
158158
local lastModified = dict:get("_lastModified")
159159
if (lastModified == nil) then
160+
ngx.log(ngx.DEBUG, "Returning the rules from the cache as lastModified is nil in the dict named=", tostring(dict_name))
160161
return cached_rules[rule_type]
161162
end
162163
-- 1. return the keys from the local variable, if lastModified date allows and if the local cache is not empty
163164
if (lastModified == last_modified_date[dict_name]) then
165+
ngx.log(ngx.DEBUG, "Returning the rules from the cache as the dict hasn't been updated in the dict named=", tostring(dict_name))
164166
return cached_rules[rule_type]
165167
end
166168
-- 2. else, read it from the shared dict
167169
-- docs: http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT.get_keys
168-
-- wil return a max os 1024 keys
170+
-- will return a max of 1024 keys
169171
cached_rules[rule_type] = {}
170172
local keys = dict:get_keys()
171-
local val_string, val, data, domain, expire_at_utc, id, meta
173+
local val_string, val, data, domain, expire_at_utc, id, meta, decode_ok
172174
local i, format_split_idx
173175
for i, key in pairs(keys) do
174176
val_string, data = dict:get(key)
175177
if (val_string ~= nil and key ~= "_lastModified") then
176178
format_split_idx = key:find(" ")
177-
val = cjson.decode(val_string)
178-
if ( val ~= nil and format_split_idx ~= nil ) then
179+
decode_ok, val = pcall(cjson.decode, val_string)
180+
if ( decode_ok and val ~= nil and format_split_idx ~= nil ) then
179181
id = key:sub(1, format_split_idx - 1)
180182
cached_rules[rule_type][i] = {
181-
id = tonumber(id) or id, -- try to convert it to a number, but if it's not the keep string
183+
id = tonumber(id) or id, -- try to convert it to a number, but if it's not keep the string
182184
format = key:sub(format_split_idx + 1),
183185
domain = val["domain"],
184186
expire_at_utc = val["expire_at_utc"],
@@ -187,7 +189,7 @@ function _M:getRulesForType(rule_type)
187189
data = data
188190
}
189191
else
190-
ngx.log(ngx.WARN, "Could not read rule from shared_dict:", tostring(key), " with val:", tostring(val))
192+
ngx.log(ngx.WARN, "Could not read rule from shared_dict:", tostring(dict_name), ", key=", tostring(key), ", val=", tostring(val))
191193
end
192194
end
193195
end

test/perl/api-gateway/tracking/requestTrackingManager.t

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use Cwd qw(cwd);
2424

2525
repeat_each(1);
2626

27-
plan tests => repeat_each() * (blocks() * 9) + 3 ;
27+
plan tests => repeat_each() * (blocks() * 9);
2828

2929
my $pwd = cwd();
3030

@@ -331,6 +331,55 @@ GET /test-request-match
331331
[error]
332332
333333
334+
=== TEST 6: test with an invalid dictionary key/value pair
335+
--- http_config eval: $::HttpConfig
336+
--- config
337+
include ../../api-gateway/tracking_service.conf;
338+
error_log ../test-logs/requestTrackingManager_test6_error.log debug;
339+
340+
location /add-invalid-entries {
341+
set_by_lua_block $generated_expires_at {
342+
-- NOTE: assumption is that ngx.now() and ngx.time() is UTC
343+
-- expire in 1 second
344+
return ( ngx.time() + 1 )
345+
}
346+
347+
content_by_lua_block {
348+
local trackingManager = ngx.apiGateway.tracking.manager
349+
local dict_name = "blocking_rules_dict"
350+
local dict = ngx.shared[dict_name]
351+
assert( dict ~= nil, "Shared dictionary not defined. Please define it with 'lua_shared_dict " .. tostring(dict_name) .. " 5m';")
352+
353+
dict:set("_lastModified", ngx.now(), 0)
354+
ngx.sleep(0.5)
355+
356+
-- add an invalid empty string in the dictionary
357+
dict:add("key1","")
358+
359+
local r = trackingManager:getRulesForType("BLOCK")
360+
assert( r ~= nil, "Results should not be nil")
361+
ngx.say(tostring(r[1]))
362+
ngx.say("added invalid value")
363+
}
364+
365+
}
366+
--- more_headers
367+
X-Test: test
368+
--- pipelined_requests eval
369+
[
370+
"GET /add-invalid-entries",
371+
"GET /tracking/block"
372+
]
373+
--- response_body eval
374+
[
375+
"nil
376+
added invalid value\n",
377+
"{}\n"
378+
]
379+
--- error_code_like eval
380+
[200,200]
381+
--- no_error_log
382+
[error]
334383
335384
336385

0 commit comments

Comments
 (0)