Я пытаюсь проанализировать полезную нагрузку json, отправленную через запрос POST в NGINX/Openresty location
. Для этого я объединил Openresty content_by_lua_block
с его cjson
module следующим образом:
# other locations above
location /test {
content_by_lua_block {
ngx.req.read_body()
local data_string = ngx.req.get_body_data()
local cjson = require "cjson.safe"
local json = cjson.decode(data_string)
local endpoint_name = json['endpoint']['name']
local payload = json['payload']
local source_address = json['source_address']
local submit_date = json['submit_date']
ngx.say('Parsed')
}
}
Анализ демонстрационных данных, содержащих все обязательные поля, работает должным образом. Правильный объект JSON может выглядеть так:
{
"payload": "the payload here",
"submit_date": "2018-08-17 16:31:51",
},
"endpoint": {
"name": "name of the endpoint here"
},
"source_address": "source address here",
}
Однако пользователь может отправить объект JSON другого формата в файл location
. Предположим, что это простой документ JSON, например
{
"username": "JohnDoe",
"password": "password123"
}
не содержащий нужных полей/ключей.
Согласно cjson
документации модуля, использование cjson
(без его режима safe
) вызовет ошибку, если будут обнаружены недопустимые данные. Чтобы предотвратить появление каких-либо ошибок, я решил использовать его режим safe
, импортировав cjson.safe
. Это должно вернуть nil
для недопустимых данных и предоставить сообщение об ошибке вместо того, чтобы вызывать ошибку:
Модуль
cjson
выдаст ошибку во время преобразования JSON, если обнаружатся какие-либо недопустимые данные. [...]Модуль
cjson.safe
ведет себя идентично модулю cjson, за исключением случаев, когда во время преобразования JSON возникают ошибки. При ошибке функцииcjson_safe.encode
иcjson_safe.decode
возвращают nil, за которым следует сообщение об ошибке.
Однако в моем случае я не сталкиваюсь с каким-либо другим поведением при обработке ошибок, и в файле error.log
Openresty показана следующая обратная трассировка:
2021/04/30 20:33:16 [ошибка] 6176#6176: *176 поток записи lua прерван: ошибка времени выполнения: content_by_lua(samplesite:50):16: попытка проиндексировать поле «конечная точка» (нулевое значение)
Что, в свою очередь, приводит к внутренней ошибке сервера:
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>openresty</center>
</body>
</html>
Я думаю, что обходной путь может заключаться в написании специальной функции для анализа данных JSON и вызове ее с помощью pcall()
для обнаружения любых ошибок. Однако это сделало бы режим safe
бесполезным. Что мне здесь не хватает?