以下代码按预期工作,但只有一次。
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)
在第二次运行时,即使是从新的浏览器窗口,我也会收到以下错误:
* 1 lua入口线程中止:运行时错误:/home/myname/code/workbench/src/handler.lua:3:尝试调用全局'loadCheckfile'(零值)
nginx.conf(仅用于开发,而不是最后的开发):
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
任何人都知道这个菜鸟又错了什么?提前致谢!
更新:
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
根据this source,我只将模块放入loadCheckfile.lua和checkValPairs.lua。甚至把它放进去 handler.lua不起作用(只需要尝试)。
答案 0 :(得分:1)
你的解决方案应该有效,但有一些事情要知道。
OpenResty为每个请求创建一个带有全新全局环境的协程(Lua绿色线程),但require()
仅加载模块一次,从不再次执行其main chunk
。因此,您在这些模块中设置的所有全局变量仅在第一次请求期间存在。此外,如果您的处理程序生成i / o,则会有第二个请求到达并窃取其部分全局变量的窗口,因此不会完成任何请求。准确的解决方案是永远不要在OpenResty中的模块中设置全局变量(在普通Lua中也是如此,因为破坏_G
通常是一个坏主意),而是遵循标准模块习惯用语:
-- 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()
这种方式模块创建一个包含函数的表,而不是将它们设置为全局变量并将其返回到require()
。 require()
每次调用都会返回它。
如果您厌倦了本地功能的可见性规则,请引入另一个local m = { }
或您喜欢的任何名称,并将所有私有内容存储在那里。在您的眼中变得丑陋之后,请选择Lua环境等高级主题(setfenv()
,setmetatable()
)。如果您不想了解详细信息,请将此行放在local M = { }
之前的每个模块中:
setfenv(1, setmetatable({ }, { __index = getfenv(0) }))
您的所有全局变量都是该模块的本地变体,因此您可以避免m
(但不是M
,仍然需要导出')。
答案 1 :(得分:0)
使用lua_code_cache off
是一个很大的性能问题,因为它会一次又一次地执行代码。试试这个
local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/check.lst")
让我知道这是否有效,我将添加解释
答案 2 :(得分:0)
<强>注意强>
请不要使用此解决方案。虽然它确实有效,但它并不好。 我会留在这里了解其中一个答案。
原始回答:
我的问题的解决方案是通过nginx.conf使模块全局化。
所以我在配置中插入了一个init_by_lua_file
,调用一个预加载的lua文件,其中包含我需要的所有函数,在全局级别提供此函数。
.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;
}
}
}
新的preLoader.lua:
require("loadCheckfile")
require("checkValPairs")
checklist = loadCheckfile("/home/myname/code/workbench/src/check.list")
最后是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)