I'm experimenting with the Nginx Lua module. Currently, my goal is simply to save certain HTTP responses to a local file on disk.
After reading a few tutorials, my understanding is that I can do this using the body_filter_by_lua directive. My approach is simply to embed some Lua code in the nginx.conf file, retrieve the response body from ngx.arg, and then use standard Lua io facilities to write it to disk.
I have never programmed in Lua before, but I've programmed extensively in other scripting languages like Python, so I found it fairly easy to learn the basics of Lua.
Still, my approach isn't working, and the nginx error.log indicates the problem is that the file object I open is nil.
Here is the Lua code I place inside the nginx.conf file (edited for clarity):
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()
';
}
So the idea here is that nginx would simply pass the request on to a proxy, and then write the response body out to a local file.
I test this using:
curl http://www.google.com --proxy http://localhost:80
But nginx returns an empty reply.
So I check the error log and see:
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"
So why is my local file variable nil? When I open up a Lua console using bash, I am able to open/create a new local file and write text to it without any issues.
So what am I doing wrong? At first I thought it might be some permissions issue and nginx is unable to write a file in the current working directory, but it's my understanding that nginx runs as root. I tried an absolute path like /home/myusername/NGINX.txt, and it still fails with a nil file. I'm not able to get a more specific error about why file is nil.
So what am I doing wrong?
io.open will return nil if it was unable to open the file. You can retrieve the error message:
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
Permission issue. No right to create/open "test.txt" there. As for me, /usr/local/nginx-1.14.2/sbin/
Solution: grant permission. in my test env., /usr/local/nginx-1.14.2/ sudo chomd -r 777
To find what real issue is, try this below, to replace your "io.open" part
handle_name, err = io.open(file,"w")
print(err)
I got "permission denied" error msg with lua statments above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With