Reputation: 41
The following code works as intended, but only one time.
require("loadCheckfile")
require("checkValPairs")
local checklist = loadCheckfile("/home/myname/code/workbench/src/check.lst")
local keyList = {}
local valList = {}
-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
-- Show wether the combination fits or not
ngx.say(doesFit)
On the second run, even from a new browser window, I get the following error:
*1 lua entry thread aborted: runtime error: /home/myname/code/workbench/src/handler.lua:3: attempt to call global 'loadCheckfile' (a nil value)
nginx.conf (only for developement, not the final one):
user root;
worker_processes 1;
daemon off;
error_log /dev/stdout warn;
events {
worker_connections 32;
}
http {
default_type text/html;
access_log off;
lua_package_path '/home/myname/code/workbench/src/?.lua;;';
server {
listen 80;
location / {
content_by_lua_file /home/myname/code/workbench/src/handler.lua;
}
}
}
loadCheckfile.lua:
local function fillChecklistTable(checklist, valueLine)
repeat
firstValLength = string.find(valueLine,"=")
firstVal = string.sub(valueLine, 1, firstValLength-1)
valueLine = string.sub(valueLine, firstValLength+1)
secondValLength = string.find(valueLine, ",")
if secondValLength ~= nil then
secondVal = string.sub(valueLine, 1, secondValLength-1)
else
secondVal = valueLine
end
if checklist[firstVal] == nil then
checklist[firstVal] = {secondVal}
else
table.insert(checklist[firstVal], secondVal)
end
if secondValLength ~= nil then
valueLine = string.sub(valueLine, secondValLength+1)
else
valueLine = nil
end
until valueLine == nil
end
checklist = {}
function loadCheckfile(checkfile)
local values = io.open(checkfile)
local valueLine = values:read()
while valueLine ~= nil do
fillChecklistTable(checklist, valueLine)
valueLine = values:read()
end
return checklist
end
Anyone got an idea what this noob did wrong again? Thanks in advance!
Update:
handler.lua
checklist = {}
local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/pw_list.txt")
local keyList = {}
local valList = {}
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
ngx.say(doesFit)
loadCheckfile.lua
module("loadCheckfile", package.seeall)
local function fillChecklistTable(checklist, valueLine)
repeat
firstValLength = string.find(valueLine,"=")
firstVal = string.sub(valueLine, 1, firstValLength-1)
valueLine = string.sub(valueLine, firstValLength+1)
secondValLength = string.find(valueLine, ",")
if secondValLength ~= nil then
secondVal = string.sub(valueLine, 1, secondValLength-1)
else
secondVal = valueLine
end
if checklist[firstVal] == nil then
checklist[firstVal] = {secondVal}
else
table.insert(checklist[firstVal], secondVal)
end
if secondValLength ~= nil then
valueLine = string.sub(valueLine, secondValLength+1)
else
valueLine = nil
end
until valueLine == nil
end
checklist = {}
function loadCheckfile.loadCheckfile(checkfile)
local values = io.open(checkfile)
local valueLine = values:read()
while valueLine ~= nil do
fillChecklistTable(checklist, valueLine)
valueLine = values:read()
end
return checklist
end
According to this source I've put the module only into the loadCheckfile.lua and checkValPairs.lua. Yet even putting it into the handler.lua didn't work (just had to try).
Upvotes: 1
Views: 2136
Reputation: 41
Attention
Please don't use this solution. While it does work it is not good. I'll leave it here to understand one of the answers.
Original answer:
The solution to my problem was to make the module global via the nginx.conf.
So I've inserted a init_by_lua_file
in the configuration, calling a preloading lua file, that contained every function I need, providing this function on a global level.
The .conf:
user root;
worker_processes 1;
daemon off; #used for developing purpose
error_log /dev/stdout warn; #as well for developing
events {
worker_connections 32;
}
http {
default_type text/html;
access_log off;
lua_package_path '/home/myname/code/workbench/src/?.lua;;';
init_by_lua_file '/home/myname/code/workbench/src/preLoader.lua';
server {
listen 80;
location / {
content_by_lua_file /home/myname/code/workbench/src/handler.lua;
}
}
}
The new preLoader.lua:
require("loadCheckfile")
require("checkValPairs")
checklist = loadCheckfile("/home/myname/code/workbench/src/check.list")
And finally the handler.lua:
local keyList = {}
local valList = {}
-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
-- Show wether the combination fits or not
ngx.say(doesFit)
Upvotes: 0
Reputation: 3000
Your solution should work, but there is something to know.
OpenResty creates a coroutine (Lua green thread) with fresh new global environment for each request, but require()
only loads module once, never executing its main chunk
again. So, all globals you set in these modules exist only during first request. Moreover, if your handler makes i/o, there is a window for second request to arrive and to steal its part of globals, so no requests will be completed. The accurate solution is to never set globals in your modules in OpenResty (and in ordinary Lua too, because spoiling _G
is a bad idea in general), but to follow the standard module idiom instead:
-- mymod.lua
local M = { }
local function private() -- for internal use
...
end
function M.public() -- to be 'exported'
...
end
return M -- this will be returned from require
-- uses_mymod.lua
local mymod = require 'mymod' -- mymod is M from above
mymod.public()
This way module creates a table with functions instead of setting them as globals and returns it to require()
. require()
will return it each time called.
When you'll become tired of local function's visibility rules, introduce another local m = { }
or whatever you like to name it, and store all privates there. After that becomes ugly in your eye, go for advanced topics like Lua environments (setfenv()
, setmetatable()
). If you don't want to go for details, put this line before local M = { }
into each module:
setfenv(1, setmetatable({ }, { __index = getfenv(0) }))
All your globals will be local to that module, so you can avoid m
(but not M
, still required for 'exports').
Upvotes: 1
Reputation: 146630
Using lua_code_cache off
is big performance issue as it is going to execute the code again and again. Try this
local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/check.lst")
Let me know if this works and I will add an explanation
Upvotes: 0