My goal is to be able to read the contents of a file (string) into a variable to be used during the execution of a plugin. Currently my code is this:
local f = io.open(filepath, “r”)
local content = ““
local content = f:read(”*a”)
This throws this exception:
attempt to index local 'f' (a nil value)
I know the path I’m giving is correct, can anyone offer guidance on this?
To avoid reading this file every time the plugin gets run, I’d like to be able to cache the results somehow to be used in future calls - is this possible?
As per the Lua reference manual:
io.open (filename [, mode])
This function opens a file, in the mode specified in the string mode. It returns a new file handle, or, in case of errors, nil plus an error message.
Error handling plays a crucial role in writing robust applications. It seems like your plugin is not checking for such errors and not taking any appropriate action upon one (thus tries to index the
nil return value).
As for your second question, you are free to cache the result of the file reading anywhere you’d like. In a Lua upvalue, in an NGINX shared dictionary, at a LuaJIT’s FFI address, in an NGINX variable… Up to you. You might want to read related literature on data sharing within and between NGINX workers.
Hi thibaultcha, thanks for responding.
It seems like no matter what, I get a nil pointer for
local f = io.open("/absolute/path/to/my/file", “r”)
I know the path is right, and the file has ALL of the permissions (chmod 777). But I can’t seem to get f to not be nil. Is there another step involved?
Did you implement error handling as recommended to find out why the file handle is
local f = assert(io.open("/absolute/path/to/my/file", “r”))
or better for ngx_lua:
local f, err = io.open()
if not f then
ngx.log(ngx.ERR, "could not open file: ", err)
Okay, figured it out!
I didn’t change anything about my code, I just moved the file and it was able to find it.
Previously, I had the file located in /home/myuser/thefile . On a hunch, I moved it to /tmp/thefile and it found it with no issues. I started kong as root, but I guess it must not have root permissions - that would explain the behavior. I feel pretty silly for not trying that earlier tbh
I have implemented your suggested errorhandler code as well; seems like good practice. Thanks so much!
I started kong as root, but I guess it must not have root permissions
NGINX worker processes do not share the same privileges as the NGINX main process, and this is by design. See the NGINX user directive, as well as its Kong counterpart: nginx_user.