我正在使用 nginx(和 OpenResty)并尝试$request_body对缓存进行哈希处理(使用srcache)。
当试图做到echo的$request_body,它完美的作品:
# actually echoes the request body
location /works {
# force loading the body
echo_read_request_body;
echo $request_body;
}
Run Code Online (Sandbox Code Playgroud)
但是当试图计算 md5 时,我得到了一个空字符串的 MD5,尽管我确保它$request_body是通过echo_read_request_body;.
# echoes d41d8cd98f00b204e9800998ecf8427e, which is the MD5 for empty input.
location /doesnt-work-md5 {
# force loading the body
echo_read_request_body;
set_md5 $digest $request_body;
echo $digest;
}
Run Code Online (Sandbox Code Playgroud)
最奇怪的现象是,在尝试复制变量时它甚至不起作用:
# echoes nothing - empty data
location /doesnt-work {
# force loading the body
echo_read_request_body;
set $temp $request_body;
echo $temp;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这些最新的片段在使用$echo_request_body代替时不起作用$request_body。
提前致谢!
在OpenResty 开发人员的帮助下,我意识到set_XYZ(ie set, set_md5) 在 nginxrewrite阶段进行评估,而$request_body/$echo_request_body仅通过该content阶段可用。
因此,在评估 时set_md5 $digest $request_body;,$request_body变量为空,这解释了常量 MD5 结果。
最终,我在自己的 API 应用程序中实现了实际的缓存密钥生成(参见下面的示例),并使用access_by_lua块访问它。
块在运行access阶段,前srcache_fetch和srcache_store被评估(它们在评估post-access和output-filter分别)。
在我自己的 API 中实现它可以更好地控制缓存键生成逻辑,这在单独使用 nginx 时很难做到(因为我不想成为一个全职的 lua 程序员)。
例如,我希望能够使用 Json 主体确定性地缓存POST请求。Json 序列化不是确定性的,因为键可以按任何顺序排列。在我的 API 中,我对键进行排序,以便生成的缓存键对于相同的数据是不变的。
此外,它简化了 的处理$request_body,因为 lua 发出的子请求只是将它转发到 API,而不管阶段或磁盘缓冲状态如何。
最终的配置看起来像
location /api {
# proxy_pass ...
# Force normal responses (no deflate, etc.) See https://github.com/openresty/srcache-nginx-module#srcache_ignore_content_encoding
proxy_set_header Accept-Encoding "";
set $cache_key "";
access_by_lua_block {
local res = ngx.location.capture('/generate-key' .. ngx.var.request_uri, {
method=ngx.HTTP_POST,
-- forwards the entire request body,
-- regardless of disk buffering!
always_forward_body=true,
args=ngx.var.args
})
if res then
ngx.var.cache_key = res.body
end
}
# ... srcache options ...
}
location /generate-key {
# proxy_pass ...
}
Run Code Online (Sandbox Code Playgroud)
示例密钥生成 API 如下:
location /api {
# proxy_pass ...
# Force normal responses (no deflate, etc.) See https://github.com/openresty/srcache-nginx-module#srcache_ignore_content_encoding
proxy_set_header Accept-Encoding "";
set $cache_key "";
access_by_lua_block {
local res = ngx.location.capture('/generate-key' .. ngx.var.request_uri, {
method=ngx.HTTP_POST,
-- forwards the entire request body,
-- regardless of disk buffering!
always_forward_body=true,
args=ngx.var.args
})
if res then
ngx.var.cache_key = res.body
end
}
# ... srcache options ...
}
location /generate-key {
# proxy_pass ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3151 次 |
| 最近记录: |