【问题标题】:Writing to a file using Nginx Lua module使用 Nginx Lua 模块写入文件
【发布时间】:2017-05-01 09:12:19
【问题描述】:

我正在尝试使用 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 的更具体的错误。

那我做错了什么?

【问题讨论】:

    标签: http nginx lua


    【解决方案1】:

    如果无法打开文件,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
    

    【讨论】:

      【解决方案2】:

      权限问题。无权在那里创建/打开“test.txt”。至于我,/usr/local/nginx-1.14.2/sbin/

      解决方案:授予权限。在我的测试环境中,/usr/local/nginx-1.14.2/sudo chomd -r 777

      要找出真正的问题,请尝试以下操作,替换您的“io.open”部分

      handle_name, err = io.open(file,"w")
      print(err)
      

      我收到 “permission denied” 错误消息,上面有 lua 语句。

      【讨论】:

        【解决方案3】:

        不是 Lua 方面的专家,但在我涉足的过程中,我在某个地方找到了将 "io.open" 调用封装在 "assert" 函数中的方法。 See docs on assert

        local file = assert(io.open("TEST.txt", "w+b"), "Inaccessible file")
        

        这可能只是确认这是代码失败的地方。看那行,我不确定 "w+b" 中的 "b" 模式是什么。

        您的意思是像 io.open("TEST.txt", "w") 那样覆盖还是像 io.open("TEST.txt", "a") 那样追加?

        如果您使用这些进行测试,但仍然出现错误,则表示该文件实际上没有被访问。

        【讨论】:

          【解决方案4】:

          我认为你应该改变:

          local file = io.open("TEST.txt", "w+b")
          

          收件人:

          local file = io.open("TEST.txt", "a")
          

          【讨论】:

            猜你喜欢
            • 2021-07-23
            • 2019-01-06
            • 1970-01-01
            • 2017-07-31
            • 2016-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多