在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
--[[ if user== "spam" then tbl = {"alpha", "beta", "gamma"} --定义table 数组 for i = 1, table.getn(tbl) do -- for循环 local deled=table.remove(tbl, 2) -- 删除指定位置元素并返回删除元素.如果没有指定删除的位置,则默认删除table的最后一个元素
for index, value in pairs(gTable) do --[[ ngx.say (table.concat( tbl, ":")) -- join
ngx.say(math.random(1,2)); --随机数 ngx.print(ngx.req.raw_header(),ngx.var.uri) -- 获取http header 信息 ngx.redirect("http://www.elong.com") --跳转
多行字符串 local longstring=[[123 456 abc 'szSuffix' ]] ngx.say(longstring)
ngx_lua安装 ngx_lua安装可以通过下载模块源码,编译Nginx,但是推荐采用openresty。Openresty就是一个打包程序,包含大量的第三方Nginx模块,比如HttpLuaModule,HttpRedis2Module,HttpEchoModule等。省去下载模块,并且安装非常方便。 ngx_openresty bundle: openresty ./configure --with-luajit&& make && make install 默认Openresty中ngx_lua模块采用的是标准的Lua5.1解释器,通过--with-luajit使用LuaJIT。
ngx.location.capture location = /other { ehco 'Hello, world!'; } # Lua非阻塞IO location = /lua { content_by_lua ' local res = ngx.location.capture("/other?id=12") if res.status == 200 then ngx.print(res.body) end '; } capture post -- POST https://www.example.com:443/foo/bar?hello=world
ngx.location.capture_multi 语法:res1,res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ...}) 与ngx.location.capture功能一样,可以并行的、非阻塞的发出多个子请求。这个方法在所有子请求处理完成后返回,并且整个方法的运行时间取决于运行时间最长的子请求,并不是所有子请求的运行时间之和。 # 同时发送多个子请求(subrequest) location = /moon { ehco 'moon'; } location = /earth { ehco 'earth'; } location = /lua { content_by_lua ' local res1,res2 = ngx.location.capture_multi({ {"/moon"}, {"earth"} }) if res1.status == 200 then ngx.print(res1.body) end ngx.print(",") if res2.status == 200 then ngx.print(res2.body) end '; } set_by_lua 和set指令一样用于设置Nginx变量并且在rewrite阶段执行,只不过这个变量是由lua脚本计算并返回的。 语法:set_by_lua$res <lua-script-str> [$arg1 $arg2 ...] location = /adder { set_by_lua $res " local a = tonumber(ngx.arg[1]) local b = tonumber(ngx.arg[2]) return a + b" $arg_a $arg_b; echo $res; } set_by_lua_file 执行Nginx外部的lua脚本,可以避免在配置文件中使用大量的转义 location = /fib { set_by_lua_file $res "conf/adder.lua" $arg_n; echo $res; } local a = tonumber(ngx.arg[1]) local b = tonumber(ngx.arg[2]) return a + b
access_by_lua和access_by_lua_file 运行在access阶段,用于访问控制。Nginx原生的allow和deny是基于ip的,通过access_by_lua能完成复杂的访问控制,比如,访问数据库进行用户名、密码验证等。 location /auth { access_by_lua ' if ngx.var.arg_user == "ntes" then return else Ngx.exit(ngx.HTTP_FORBIDDEN) end '; echo 'welcome ntes'; } 输出: $ curl 'localhost/auth?user=sohu' $ Welcome ntes $ curl 'localhost/auth?user=ntes' $ <html> <head><title>403 Forbidden</title></heda> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>ngx_openresty/1.0.10.48</center> </body> </html> rewrite_by_lua和rewrite_by_lua_file 实现url重写,在rewrite阶段执行。 配置: location = /foo { rewrite_by_lua 'ngx.exec("/bar")'; echo 'in foo'; } location = /bar { echo 'Hello, Lua!'; } 输出: $ curl 'localhost/lua' $ Hello, Lua! content_by_lua和content_by_lua_file Contenthandler在content阶段执行,生成http响应。由于content阶段只能有一个handler,所以在与echo模块使用时,不能同时生效,我测试的结果是content_by_lua会覆盖echo。这和之前的hello world的例子是类似的。 location = /lua { content_by_lua 'ngx.say("Hello, Lua!")'; }
os.execute ([command]) 例如: 输出:
os.exit ([code]) 例如: os.getenv (varname) 例如: print(os.getenv("USERDOMAIN")) print(os.getenv("SystemRoot")) print(os.getenv("Os2LibPath")) print(os.getenv("ProgramFiles" )) print(os.getenv("APPDATA" )) print(os.getenv("ALLUSERSPROFILE" )) print(os.getenv("CommonProgramFiles" )) print(os.getenv("COMPUTERNAME" )) print(os.getenv("USERNAME")) print(os.getenv("USERPROFILE" )) print(os.getenv("ComSpec")) print(os.getenv("LOGONSERVER" )) print(os.getenv("NUMBER_OF_PROCESSORS" )) print(os.getenv("OS")) print(os.getenv("PATHEXT" )) print(os.getenv("PROCESSOR_ARCHITECTURE" )) print(os.getenv("PROCESSOR_IDENTIFIER" )) print(os.getenv("PROCESSOR_LEVEL" )) print(os.getenv("PROCESSOR_REVISION" )) print(os.getenv("USERDOMAIN")) print(os.getenv("SystemRoot" )) print(os.getenv("TEMP"))
输出: RDEV C:\WINDOWS nil C:\Program Files C:\Documents and Settings\baiyun\Application Data C:\Documents and Settings\All Users C:\Program Files\Common Files BAIYUN baiyun C:\Documents and Settings\baiyun C:\WINDOWS\system32\cmd.exe http://www.cnblogs.com/whiteyun/admin/file://rdev1/ 2 Windows_NT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.py;.pyw;.wlua x86 x86 Family 15 Model 6 Stepping 5, GenuineIntel 15 0605 RDEV C:\WINDOWS C:\DOCUME~1\baiyun\LOCALS~1\Temp os.remove (filename) os.rename (oldname, newname) 调取 mysql json redis操作 ngx.say("=============== mysql ==============") local mysql = require "resty.mysql" local db,err = mysql:new() if not db then ngx.say("failed to instantiate mysql: ",err) return end db:set_timeout(1000) local ok,err,errno,sqlstate = db:connect{ host = "127.0.0.1", port = 3306, database = "el_agency", user = "root", password = "", max_package_size = 1024 } if not ok then ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate) return end
执行顺序 1.init_by_lua 上下文http ngx启动时执行 2.set_by_lua 上下文 server, server if, location, location if 3.rewrite_by_lua 上下文 http, server, location, location if 4.access_by_lua 上下文 http, server, location, location if 5.content_by_lua 上下文 location, location if 6.header_filter_by_lua 上下文 http, server, location, location if 7.body_filter_by_lua 上下文 http, server, location, location if 8.log_by_lua 上下文 http, server, location, location if lua中 三目运算符的实现 (a and b) or c <==> a ? b : c lua urlencode urldecode URL编码 function decodeURI(s) s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end) return s end function encodeURI(s) s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end) return string.gsub(s, " ", "+") end
LUA require 搜索路径指定方法 如果是一个 *.LUA 的文件, 里面用到了自己写的库, 或者第三方写的库, 但是你不想把它放到 lua 的安装目录里, 则在代码里面可以指定require搜索的路径。 package.path = '/usr/local/share/lua/5.1/?.lua;/home/resty/?.lua;;' --搜索lua模块 ;;指定默认路径 package.cpath = '/usr/local/lib/lua/5.1/?.so;;' --搜索so模块 如果是要在 nginx.conf 文件中引用第三方的库,则需要在 http 段中添加下面的代码 lua_package_path '/usr/local/share/lua/5.1/?.lua;/home/resty/?.lua;'; lua_package_cpath '/usr/local/lib/lua/5.1/?.so;'; lua下面dump出一个table的结构 --- @brief 调试时打印变量的值 --- @param data 要打印的字符串 --- @param [max_level] table要展开打印的计数,默认nil表示全部展开 --- @param [prefix] 用于在递归时传递缩进,该参数不供用户使用于 --- @ref http://dearymz.blog.163.com/blog/static/205657420089251655186/ function var_dump(data, max_level, prefix) if type(prefix) ~= "string" then prefix = "" end if type(data) ~= "table" then print(prefix .. tostring(data)) else print(data) if max_level ~= 0 then local prefix_next = prefix .. " " print(prefix .. "{") for k,v in pairs(data) do io.stdout:write(prefix_next .. k .. " = ") if type(v) ~= "table" or (type(max_level) == "number" and max_level <= 1) then print(v) else if max_level == nil then var_dump(v, nil, prefix_next) else var_dump(v, max_level - 1, prefix_next) end end end print(prefix .. "}") end end end
ngx.exec location @cc { internal; root html; index index.html index.htm; } 代码中 ngx.exec("@cc")
iptolong -- 参数:待分割的字符串,分割字符 -- 返回:子串表.(含有空串) function split(s, delim) if type(delim) ~= "string" or string.len(delim) <= 0 then return end local start = 1 local t = {} while true do local pos = string.find (s, delim, start, true) -- plain find if not pos then break end table.insert (t, string.sub (s, start, pos - 1)) start = pos + string.len (delim) end table.insert (t, string.sub (s, start)) return t end --ip转整数 function ip2long(ip) local ips=split(ip,".") local num = 0 for i,v in pairs(ips) do num =num +(tonumber(v) * math.pow(256,#ips-i)) end return num end
获取当前路径及上级目录 function dirname(str) if str:match(".-/.-") then local name = string.gsub(str, "(.*/)(.+)", "%1") return name elseif str:match(".-\\.-") then local name = string.gsub(str, "(.*\\)(.+)", "%1") return name else return '' end end local __FILE__ = debug.getinfo(1,'S').source:sub(2) ROOT_PATH=dirname(__FILE__)
lua 创建一个“类” 并返回“类”中的所有方法 --helper.lua local _M = { _VERSION = '0.09' } function _M.to_hex(s) end function _M.atoi (s) end return _M local helper=require 'helper' var_dump(helper) 返回 ["to_hex"] = function: 0x0cd26038, ["atoi"] = function: 0x0cd260e8, ["_VERSION"] = "0.09",
package.seeall --game.lua module(..., package.seeall) --- ...不定参数 function play() return "ok just do it"end function quit() return "welcome back again"end Nginx中Lua模块的运行机制 Nginx中的每个Worker进程使用一个lua虚拟机,工作进程中的所有协程共享虚拟机。将Nginx中的lua API封装好之后注入到lua的VM中就可以在lua代码中进行访问
异常捕获pcall local user = ngx.var.arg_user local st,err=pcall(function() if (user == "spam"){
//todo
}else{
throw New Exception("出错啦")
}
|
请发表评论