使用Nginx Lua模块

时间:2016-12-15 17:09:37

标签: 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的原因提出更具体的错误。

那么我做错了什么?

4 个答案:

答案 0 :(得分:1)

权限问题。无权在那里创建/打开“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 语句。

答案 1 :(得分: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 :(得分:0)

不是Lua的专家,但是在我的dabling中,我选择在“断言”函数中包含“io.open”调用。 See docs on assert

       <ion-item class="item range range-positive" ng-show="value"> 
                <input type="range" name="volume" min="1" max="10" value="0" default="4" ng-model="range" ng-change="slider(range)">{{range}}
    </ion-item>

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

你的意思是在 local file = assert(io.open("TEST.txt", "w+b"), "Inaccessible file") 中覆盖,或者在 io.open("TEST.txt", "w") 中追加?

如果您使用这些测试并仍然收到错误,则表示该文件实际上未被访问。

答案 3 :(得分:0)

我认为您应该更改:

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

收件人:

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