我在上面添加我自已的路由处理.中间要用到redis 与postgresql. postgresql 连接问题已经解决.redis 一直不行.
~/workspace/openresty-china$ cat app/routes/iot.lua
local pairs = pairs
local ipairs = ipairs
local smatch = string.match
local slower = string.lower
local ssub = string.sub
local slen = string.len
local pbkdf2 = require "resty.nettle.pbkdf2"
local base64 = require "resty.nettle.base64"
local hmac = require "resty.nettle.hmac"
local gsub = string.gsub
local byte = string.byte
local format = string.format
local cjson = require("cjson")
local utils = require("app.libs.utils")
local pwd_secret = require("app.config.config").pwd_secret
local lor = require("lor.index")
local user_model = require("app.model.user")
local iot_router = lor:Router()
local config = require("app.config.config")
--- 加了一段代码会报错
local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(1000)
local ok,err = red:connect("127.0.0.1",6379)
if not ok then
ngx.log(ngx.ERR ,"connect redis error")
end
ok , err = red:auth("f4e4821080c")
if not ok then
ngx.say("auth is failed ",err)
return ok,err
end
red:select(1)
----
local UnkownSignMethod = {err="UnkownSignMethod", msg="未知签名方法", ok=false}
local SignError = {err="SignError", msg="签名错误", ok=false}
local DataMiss = {err="DataMiss", msg="信息不完整", ok=false}
local UserNotExists = {err= "UserNotExists", msg="用户不存在", ok=false}
local UnAuth = {err= "UnAuth", msg="无权访问", ok=false}
local TargetNotExists = {err= "TargetNotExists", msg="目标不存在", ok=false}
local TargetIsSelf = {err= "TargetIsSelf", msg="目标不能是自已", ok=false}
local UnkownAction = {err="UnkownAction", msg="未识别的操作", ok=false}
local BindError = {err="BindError", msg="已经绑定", ok=false}
local BindPWDError = {err="BindError", msg="无权绑定", ok=false}
local UserError = {err="UserError", msg="用户名已存在", ok=false}
local EmailError = {err="EmailError", msg="邮箱已存在", ok=false}
local PhoneError = {err="PhoneError", msg="手机号已存在", ok=false}
local PwdError = {err="PwdError", msg="密码或者用户错误", ok=false}
local ArgError = {err="ArgError", msg="参数错误", ok=false}
local CaptchaError = {err="CaptchaError", msg="验证码错误", ok=false}
local IpAddrError = {err="IpAddrError", msg="IP错误", ok=false}
local InternalError = {err="InternalError", msg="服务器内部错误", ok=false}
local SmsOverError = {err="SmsOverError", msg="该手机号已经超过发送次数", ok=false}
local SmsIntervalError = {err="SmsIntervalError", msg="发送间隔太短", ok=false}
local OtherError = {err="OtherError", msg="发送间隔太短", ok=false}
local PhoneInactive = {err="PhoneInactive", msg="该手机号没有验证激活", ok=false}
local FormatError = {err="FormatError", msg="格式错误", ok=false}
local DevActError = {err="DevActError", msg="设备未出厂", ok=false}
local function hex(str,spacer)
return (gsub(str,"(.)",function (c)
return format("%02X%s",byte(c),spacer or "")
end))
end
local function checkuuid(uuid)
local x = "%x"
local t = {x:rep(8),x:rep(4),x:rep(4),x:rep(4),x:rep(12)}
local t2 = x:rep(32)
local pattern = table.concat(t,'%-')
if string.match(uuid,pattern) or string.match(uuid,t2) then
return true
else
return false
end
end
-- 这里是为了兼django插入的加密认证方式, key = "<algorithm>$<iterations>$<salt>$<hash>"
local function check_password(oldpwd,newpwd)
-- a1,a2,a3,a4= string.match(oldpwd,"(%w+_%w+)%$(%d+)%$(%w+)%$([A-Za-z0-9+/]+)")
-- ngx.log(ngx.ERR,"match is ",a1,"||",a2,"||",a3,"||",a4)
local algorithm,iterations,salt,hash = string.match(oldpwd,"(%w+_%w+)%$(%d+)%$(%w+)%$([A-Za-z0-9+/=]+)")
-- ngx.log(ngx.ERR,"split pass ",oldpwd," ",algorithm,iterations,salt,hash)
if not algorithm or not iterations or not salt or not hash then
return false
end
local hmac
if algorithm == "pbkdf2_sha256" then
hmac = pbkdf2.hmac_sha256(newpwd,tonumber(iterations),salt,32)
-- ngx.log(ngx.ERR,"algoritm is ",algorithm)
elseif algorithm == "pbkdf2_sha1" then
-- ngx.log(ngx.ERR,"algoritm is ",algorithm, "new pwd is ", newpwd)
hmac = pbkdf2.hmac_sha1(newpwd,tonumber(iterations),salt,20)
end
-- ngx.log(ngx.ERR,"hash is ",hash, " new hash ",base64.encode(hmac))
if hash == base64.encode(hmac) then
-- ngx.log(ngx.ERR,"check password is true")
return true
end
return false
end
iot_router:get("/app",function(req,res,next)
local args = ngx.req.get_uri_args()
local usertoken = args.uuid
local userpass = args.key
if not usertoken or not userpass or usertoken == "" or userpass == "" then
return res:json(DataMiss)
end
local result,err = user_model:query_by_iot_login(usertoken)
-- ngx.log(ngx.ERR,"query sql error ",err)
if err then
return res:json(PwdError)
end
-- ngx.log(ngx.ERR,"uuid ",result.uuid," key ",result.key, " active ",result.phone_active)
local uuid,key,phone_active
if #result == 3 then
uuid = result[1]
key = result[2]
phone_active = result[3]
else
uuid = result.uuid
key = result.key
phone_active = result.phone_active
end
if not phone_active then
return res:json(PhoneInactive)
end
if result and not err then
if check_password(key,tostring(userpass)) then
-- 登录成功
local srvres ,err = user_model:query_by_mqtt_srv()
local servers = nil
if srvres and not err then
if #srvres == 2 then
servers = srvres[1] .. ":" .. srvres[2]
else
servers = srvres.ipaddr .. ":" .. srvres.port
end
end
local timestamp = string.format("%d",os.time())
local hash = hmac.sha1.new(timestamp)
hash:update(key)
local signid = hex(hash:digest())
-- ngx.log(ngx.ERR,"sigin id is ",signid)
local hash256 = hmac.sha256.new(timestamp)
hash256:update(uuid)
-- ngx.log(ngx.ERR, "hash256 is ",type(hash256))
ngx.log(ngx.ERR,"search redis path ",package.searchpath('resty.redis',package.path))
ngx.log(ngx.ERR,"search postgres path ",package.searchpath('resty.postgres',package.path))
-- red:hset(signid,"password",hex(hash256:digest()))
-- red:hset(signid,"uuid",result.uuid)
-- red:expire(signid,config.settings.SESSION_COOKIE_AGE)
retable = {}
retable.ok= true
retable.sign = signid
retable.time = timestamp
retable.expire = config.settings.SESSION_COOKIE_AGE
if servers then
retable.servers = servers
end
return res:json(retable)
else
return res:json(PwdError)
end
end
return res:json(UserNotExists)
end)
return iot_router
--------------------------------------------------------------------------------------
如果是这样写必定会出错,nginx 报错如下:
2016/12/16 15:14:46 [error] 10248#0: *34 lua entry thread aborted: runtime error: attempt to yield across C-call boundary
stack traceback:
coroutine 0:
[C]: in function 'require'
/home/yjdwbj/workspace/openresty-china/./app/main.lua:9: in function </home/yjdwbj/workspace/openresty-china/./app/main.lua:1>, client: 192.168.8.31, server: , request: "GET /iot/app?uuid=abc&key=123456 HTTP/1.1", host: "
127.0.0.1:8888"
---------------------------------------------------------------------------------------------------
如果去掉开头那些连接redis的代码就能正常运行.问题代码如下:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(1000)
local ok,err = red:connect("127.0.0.1",6379)
if not ok then
ngx.log(ngx.ERR ,"connect redis error")
end
ok , err = red:auth("f4e4821080c")
if not ok then
ngx.say("auth is failed ",err)
return ok,err
end
red:select(1)
>>>>>>>>>>>>>>>>>>>>>>
但是如果把上面这段代码放在 iot_router:get("/app",function(req,res,next)) 函数里面,运行又是正常的.请大家指教.如何通过openresty 连接到postgresql pool 与 redis pool . 不胜感激.