Lua - 变量(对)连接转义特殊字符 - Openresty Nginx
我不使用Lua,但需要在Openresty(nginx)中使用它,如链接所提供的那样。
Openresty有一个Lua模块 _我成功安装并正确运行了Openresty nginx版本,网站工作正常_。
这个 答案 显示如何将头部连接为字符串 $request_headers:
set_by_lua $request_headers '
local h = ngx.req.get_headers()
local request_headers_all = ""
for k, v in pairs(h) do
request_headers_all = request_headers_all .. "["..k..": "..v..\n"]"
end
return request_headers_all
';
我将上面Lua函数中的格式从 ""..k..": "..v..";" 改为了 "["..k..": "..v.."]"。
日志格式:
log_format log_realip 'Host: "$host", Via : "$http_via", RemoteAddr: "$remote_addr", XForwardedFor: "$h
ttp_x_forwarded_for", 'RealIPRemoteAddr: "$realip_remote_addr" - $status - "$request_uri" - **"[HEADERS]" - $request_headers';**
Host: "192.168.1.4", Via : "-",
//仅显示[HEADERS]
....
"[HEADERS]" - [sec-ch-ua: \x22Chromium\x22;v=\x2288\x22, \x22Google Chrome\x22;v=\x228
8\x22, \x22;Not A Brand\x22;v=\x2299\x22][sec-ch-ua-mobile: ?0][cookie: __utmz=abcdef; frontend=abcdef; adminhtml=abcdef
08; TestName=Some Value][upgrade-insecure-requests: 1][accept-language: en-US,en;q=0.9][user-agent: Mozilla/5.0
(Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36][accept
-encoding: gzip, deflate, br][accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/we
bp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9][sec-fetch-dest: document][host: 192.168.1.4][se
c-fetch-user: ?1][connection: keep-alive][sec-fetch-mode: navigate][cache-control: max-age=0][sec-fetch-site: n
one
当使用 $request_headers 字符串的 log_format 时,我得到了所有头部的字符串。但我试图创建一个 newline \n 将字符串分成几行。上面的例子是我添加了 \n,但看起来并未输出换行符到日志文件中。
我理解 request_headers_all .. 将字符串连接起来,但是这里的 key k 和 value v : ""..k..": "..v..\n"" 是什么意思?
"..variablename.." 是什么意思,这是变量始终在Lua字符串内使用的方法吗?
我该如何在该字符串中创建换行符?或者nginx(openresty)无法输出换行符?
如果你将 \n 添加到错误的位置,你可以改为 request_headers_all = request_headers_all .. "["..k..": "..v.."]\n" 添加一个换行记录。
在 Lua 中,.. 是一个连接符,用于连接两个字符串,例如:
print("hello" .. "world")
结果为 helloworld。
你的代码 \n"]" 存在语法错误,因为 \n 不在字符串中。
Lua 字符串不能直接使用变量,通常使用 string.format 处理复杂的字符串。例如:
local test = "hello"
string.format("%s world",test) -- hello world
你可以使用 string.format 进行字符串连接。此外,你还可以使用 table.concat 来连接字符串。例如:
local test = {}
table.insert(test, "hello")
table.insert(test, "world")
local concated_string = table.concat(test, ' ')
print(concated_string) -- hello world
上面的回答给了我一些指导,但是建议的格式仍然无法正常工作。在尝试使用string.format("%s %s\n",k,v)、string.format("%s %s\\n",k,v)后,我仍然遇到了unfinished string错误或没有输出换行符(在第二个示例中尝试了转义字符串)。
基于给出的答案,我认为答案给出了正确的lua信息,所以决定最有可能的情况是lua + openresty做了不同的事情。
我将尝试更新标题以反映更具体的要求
TLDR
- 特殊字符的Openresty + lua字符串操作可能无法按预期工作,即使使用
string.format() - 从返回字符串的
set_by_lua更改为允许更好的string.format()或字符串连接的set_by_lua_block - 根据您的自定义/现有
log_format更新nginx配置,并添加开关escape = none。
全面解释
调查提供的链接答案set_by_lua函数文档:
注意自v0.9.17发布以来,不建议使用此指令。使用set_by_lua_block指令。
因此从原始的链接中的set_by_lua更改为:
set_by_lua $request_headers '
return 'stringvalue'
';
我改为set_by_lua_block函数:
这个指令将Lua源直接内联在一对大括号({})中,而不是在一个Nginx字符串文字中(需要特殊字符转义)
set_by_lua_block $request_headers{
local h = ngx.req.get_headers()
local request_headers_all = ""
for k, v in pairs(h) do
local rowtext = ""
rowtext = string.format("[%s %s]\n", k, v)
request_headers_all = request_headers_all .. rowtext
end
return request_headers_all
}
重要的部分是这个_block {}函数正确地转义特殊字符。
然后我在日志文件中收到的输出为:x0A(换行字符文字)。
最后一步是更新nginx.conf文件与自定义log_format并添加escape=none:
log_format log_realip escape=none "$nginx_variables"
主要问题/难点在于包装软件如何处理换行符/转义字符,它是期望 "\n" 还是期望 "\r\n"?
最终换行符只有在解释和打印后才实际存在,并且您正在创建一个从 Lua 引擎返回给包装器的大字符串,因此如何解释换行符取决于包装软件。
编辑:我错过了使用其他解析函数已经回答了这个问题。
此外,文档中指出,要使用原始解析函数,需要对转义字符进行双重转义。
在这里,\\\\d+ 通过 Nginx 配置文件解析器被简化为 \\d+,在运行之前被 Lua 语言解析器进一步简化为 \d+。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

request_headers_all = request_headers_all .. "["..k..": "..v.."]\n"这里包含语法错误。将
"["..k..": "..v..\n"]"替换为"["..k..": "..v.."]\n"。换行需要处于引号内,因为它是字符串的一部分,很可能在括号后添加换行符才有意义。
在变量上使用连接运算符会连接字符串值,如果是数字则连接其字符串表示形式,如果两者都不是,则调用
__concat或者引发错误。请参阅 https://www.lua.org/manual/5.4/manual.html#3.4.6。