http - 使用 Nginx Lua 模块写入文件

标签 http nginx lua

我正在尝试 Nginx Lua module 。目前,我的目标只是将某些 HTTP 响应保存到磁盘上的本地文件中。

阅读了一些教程后,我的理解是我可以使用 body_filter_by_lua 来做到这一点指示。我的方法只是在 nginx.conf 文件中嵌入一些 Lua 代码,从 ngx.arg 中检索响应正文,然后使用标准 Lua io 将其写入磁盘的设施。

我以前从未使用 Lua 进行过编程,但我已经使用 Python 等其他脚本语言进行过广泛的编程,因此我发现学习 Lua 的基础知识相当容易。

不过,我的方法不起作用,nginx error.log 表明问题是我打开的 file 对象是 nil.

这是我放置在 nginx.conf 文件中的 Lua 代码(为了清晰起见进行了编辑):

   location /foo {
        proxy_pass http://my_upstream_proxy;
        proxy_cache my_cache;
        proxy_redirect default;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        body_filter_by_lua '
            local resp_body = ngx.arg[1]
            ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
            if ngx.arg[2] then
                ngx.var.resp_body = ngx.ctx.buffered
            end

            local file = io.open("TEST.txt", "w+b")
            file:write(resp_body)
            file:close()
        ';
    }

所以这里的想法是,nginx 会简单地将请求传递给代理,然后将响应正文写入本地文件。

我使用以下方法对此进行测试:

curl http://www.google.com --proxy http://localhost:80

但是 nginx 返回一个空回复。

所以我检查错误日志并看到:

2016/12/15 11:51:00 [error] 10056#0: *1 failed to run body_filter_by_lua*: body_filter_by_lua:9: attempt to index local 'file' (a nil value)
stack traceback:
        body_filter_by_lua:9: in function <body_filter_by_lua:1> while sending to client, client: 127.0.0.1, server: test-server, request: "GET http://www.google.com/ HTTP/1.1", upstream: "http://69.187.22.138:82/", host: "www.google.com"

那么为什么我的本地file变量是nil?当我使用 bash 打开 Lua 控制台时,我可以打开/创建一个新的本地文件并向其中写入文本,没有任何问题。

那我做错了什么?起初我认为这可能是一些权限问题,nginx 无法在当前工作目录中写入文件,但据我了解,nginx 以 root 身份运行。我尝试了像 /home/myusername/NGINX.txt 这样的绝对路径,但它仍然失败并显示 nil 文件。我无法获得有关为什么 filenil 的更具体错误。

那么我做错了什么?

最佳答案

如果无法打开文件,io.open 将返回 nil。您可以检索错误消息:

local file, err = io.open("TEST.txt", "w+b")
if file == nil then
    print("Couldn't open file: " .. err)
else
    file:write(resp_body)
    file:close()
end

关于http - 使用 Nginx Lua 模块写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41169712/

相关文章:

lua - 如何在lua中读取大文件(> 1GB)?

sdk - 如何在 Lua 中显示数组元素?

python - 相当于 Lua 的 pairs() 用于 Python

带有 GET 方法的 Angular HttpClient 参数不起作用

java - 通过 Web 的 API : use 80 port or a custom one (like 8080)?

postgresql - 经常更新的最佳缓存策略数据(Redis/Memcached vs Nginx/Varnish vs Materialized view)

nginx - 如何将GET参数放在nginx重写规则中?

rest - RESTful API 可以在一个请求中返回多个资源吗?

http - 基本 HTTP 身份验证可以使用默认用户名吗?

nginx - 浏览器未接收/解释来自 Nginx 的 413 响应