增加新的文件和相关测试文件
This commit is contained in:
parent
81d224affe
commit
5aea1f82fa
|
@ -1,18 +1,104 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/25 14:19
|
||||
--- DateTime: 2025/9/24 15:29
|
||||
---
|
||||
|
||||
-- local user = require('api.system.user')--- 启动调试
|
||||
-- local mobdebug = require('src.share.initial.mobdebug');
|
||||
-- mobdebug.start();
|
||||
|
||||
local function say_hello(req)
|
||||
ngx.say("Hello, World!")
|
||||
end
|
||||
|
||||
local function get_user(req)
|
||||
ngx.say("call get_user")
|
||||
local user_id = req.args.id or "unknown"
|
||||
ngx.say("User ID: " .. user_id)
|
||||
end
|
||||
|
||||
local function get_id(req)
|
||||
ngx.say("call get_id")
|
||||
local args = req.get_uri_args()
|
||||
-- 获取单个参数
|
||||
local id = args["id"] -- 值为 "john"
|
||||
ngx.say("User ID: " .. user_id)
|
||||
end
|
||||
|
||||
local function test(req)
|
||||
local request_method = ngx.var.request_method
|
||||
local args = nil
|
||||
ngx.say(request_method)
|
||||
|
||||
--1、获取参数的值 获取前端提交参数
|
||||
if "GET" == request_method then
|
||||
args = ngx.req.get_uri_args()
|
||||
elseif "POST" == request_method then
|
||||
ngx.req.read_body()
|
||||
args = ngx.req.get_post_args()
|
||||
end
|
||||
|
||||
--2、组合url请求Get/Post请求 并获取参数
|
||||
local http = require "resty.http"
|
||||
local httpc = http.new()
|
||||
local url = "http://xxxxx/user/login/"..args["userid"].."/"..args["pass"]
|
||||
local resStr --响应结果
|
||||
local res, err = httpc:request_uri(url, {
|
||||
method = "GET",
|
||||
--args = str,
|
||||
body = "a=1&b=2",
|
||||
headers = {
|
||||
["Content-Type"] = "application/json",
|
||||
}
|
||||
})
|
||||
|
||||
--3、开始重新组合参数 例子 可根据返回的JSON自己处理
|
||||
local cjson = require "cjson"
|
||||
local sampleJson = [[{"age":"23","testArray":{"array":[8,9,11,14,25]},"Himi":"himigame.com"}]];
|
||||
--解析json字符串
|
||||
local data = cjson.decode(sampleJson);
|
||||
--打印json字符串中的age字段
|
||||
ngx.say(data["age"]);
|
||||
--打印数组中的第一个值(lua默认是从0开始计数)
|
||||
ngx.say(data["testArray"]["array"][1]);
|
||||
|
||||
--4、打印输出新返回值
|
||||
ngx.say(res.body)
|
||||
|
||||
--获取url中a的值
|
||||
ngx.say(ngx.var.arg_a);
|
||||
--获取主机名
|
||||
ngx.say(ngx.var.remote_addr);
|
||||
--获取get和post参数
|
||||
local arg = ngx.req.get_uri_args()
|
||||
for k,v in pairs(arg) do
|
||||
ngx.say("[GET ] key:", k, " v:", v)
|
||||
end
|
||||
|
||||
ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
|
||||
local arg = ngx.req.get_post_args()
|
||||
for k,v in pairs(arg) do
|
||||
ngx.say("[POST] key:", k, " v:", v)
|
||||
end
|
||||
end
|
||||
|
||||
---local function conn()
|
||||
--- local conn1 = user.conn
|
||||
--- conn1:connect(...)
|
||||
---end
|
||||
|
||||
local routes = {
|
||||
["/hello"] = say_hello,
|
||||
["/user"] = get_user,
|
||||
["/userid"] = get_id,
|
||||
}
|
||||
|
||||
local function handle_request()
|
||||
local request_method = ngx.var.request_method
|
||||
local args = nil
|
||||
ngx.say(request_method)
|
||||
|
||||
local uri = ngx.var.request_uri
|
||||
ngx.say("url: " .. uri)
|
||||
local handler = routes[uri]
|
||||
|
|
34
src/api/system/user.lua
Normal file
34
src/api/system/user.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/25 08:19
|
||||
---
|
||||
|
||||
local db_config = require('config.database')
|
||||
local pgmoon = require('share.pgmoonn')
|
||||
|
||||
-- 创建一个新的连接
|
||||
local conn = pgmoon.new(db_config.postgres)
|
||||
|
||||
-- 连接到数据库
|
||||
conn:connect(function(err)
|
||||
if err then
|
||||
print("Error connecting to database: ", err)
|
||||
else
|
||||
print("Connected to the PostgreSQL server.")
|
||||
|
||||
-- 执行一个简单的查询
|
||||
conn:query("SELECT version()")
|
||||
:on_data(function(row)
|
||||
print("Database Version: ", row[1])
|
||||
end)
|
||||
:on_error(function(err)
|
||||
print("Query Error: ", err)
|
||||
end)
|
||||
:on_finish(function()
|
||||
print("Query finished.")
|
||||
-- 关闭连接
|
||||
conn:close()
|
||||
end)
|
||||
end
|
||||
end)
|
25
src/config/config.lua
Normal file
25
src/config/config.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/24 16:31
|
||||
---
|
||||
|
||||
return {
|
||||
APP_ENV = "dev", -- dev/prod
|
||||
|
||||
-- 配置redis数据库连接
|
||||
REDIS = {
|
||||
HOST = "127.0.0.1", -- redis host
|
||||
PORT = 6379, -- redis port
|
||||
PASSWORD = nil -- redis password
|
||||
},
|
||||
|
||||
-- 配置PostgresSQL数据库连接
|
||||
POSTGRES = {
|
||||
HOST = "127.0.0.1", -- postgres host
|
||||
PORT = 5432, -- postgres port
|
||||
USERNAME = "postgres",
|
||||
PASSWORD = "123456", -- postgres password
|
||||
DATABASE = "postgres"
|
||||
}
|
||||
}
|
18
src/config/database.lua
Normal file
18
src/config/database.lua
Normal file
|
@ -0,0 +1,18 @@
|
|||
local env = require('env')
|
||||
|
||||
return {
|
||||
redis_prefix = 'Auth:',
|
||||
redis = {
|
||||
host = env.REDIS.HOST,
|
||||
port = env.REDIS.PORT,
|
||||
password = env.REDIS.PASSWORD
|
||||
},
|
||||
|
||||
postgres = {
|
||||
host = env.POSTGRES.HOST,
|
||||
port = env.POSTGRES.PORT,
|
||||
username = env.POSTGRES.USERNAME,
|
||||
password = env.POSTGRES.PASSWORD,
|
||||
dbname = env.POSTGRES.DATABASE
|
||||
},
|
||||
}
|
18
src/routes/dynamic_router.lua
Normal file
18
src/routes/dynamic_router.lua
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/24 18:14
|
||||
---
|
||||
|
||||
local cjson = require("cjson.safe")
|
||||
local routes = require("routes_cache") -- 从共享内存获取
|
||||
function handle_request()
|
||||
local target = routes:get(ngx.var.uri)
|
||||
if not target then
|
||||
ngx.status = 404
|
||||
ngx.say("Route not found: ", ngx.var.uri)
|
||||
return
|
||||
end
|
||||
ngx.var.target = target
|
||||
end
|
||||
handle_request()
|
15
src/routes/route_updater.lua
Normal file
15
src/routes/route_updater.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/24 18:14
|
||||
---
|
||||
|
||||
local cjson = require("cjson")
|
||||
local dict = ngx.shared.routes_cache
|
||||
ngx.req.read_body()
|
||||
local body = ngx.req.get_body_data()
|
||||
local new_rules = cjson.decode(body)
|
||||
for path, target in pairs(new_rules) do
|
||||
dict:set(path, target)
|
||||
end
|
||||
ngx.say(cjson.encode({ status = "ok", count = #new_rules }))
|
5
src/service/system/user.lua
Normal file
5
src/service/system/user.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by admin.
|
||||
--- DateTime: 2025/9/25 08:19
|
||||
--- 业务逻辑
|
29
src/share/initial/loading_config.lua
Normal file
29
src/share/initial/loading_config.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||
--- Created by .
|
||||
--- DateTime:
|
||||
---
|
||||
|
||||
--[[
|
||||
公共包引用的范围为http块;项目用到的非配置类都可以在此处配置;
|
||||
日志级别:
|
||||
ngx.STDERR
|
||||
ngx.EMERG
|
||||
ngx.ALERT
|
||||
ngx.CRIT
|
||||
ngx.ERR
|
||||
ngx.WARN
|
||||
ngx.NOTICE
|
||||
ngx.INFO
|
||||
ngx.DEBUG
|
||||
]]
|
||||
-- 加载cjson
|
||||
cjson = require("cjson");
|
||||
-- 加载string
|
||||
string = require("string");
|
||||
|
||||
--[[
|
||||
项目内公共包配置
|
||||
]]
|
||||
-- 加载resty.core
|
||||
require("resty.core");
|
1703
src/share/initial/mobdebug.lua
Normal file
1703
src/share/initial/mobdebug.lua
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/share/lib/cjson.so
Normal file
BIN
src/share/lib/cjson.so
Normal file
Binary file not shown.
1
src/share/pgmoon.lua
Normal file
1
src/share/pgmoon.lua
Normal file
|
@ -0,0 +1 @@
|
|||
return require('pgmoon.init')
|
196
src/share/pgmoon/arrays.lua
Normal file
196
src/share/pgmoon/arrays.lua
Normal file
|
@ -0,0 +1,196 @@
|
|||
local OIDS = {
|
||||
boolean = 1000,
|
||||
number = 1231,
|
||||
string = 1009,
|
||||
array_json = 199,
|
||||
array_jsonb = 3807
|
||||
}
|
||||
local is_array
|
||||
is_array = function(oid)
|
||||
for k, v in pairs(OIDS) do
|
||||
if v == oid then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
local PostgresArray
|
||||
do
|
||||
local _class_0
|
||||
local _base_0 = { }
|
||||
_base_0.__index = _base_0
|
||||
_class_0 = setmetatable({
|
||||
__init = function() end,
|
||||
__base = _base_0,
|
||||
__name = "PostgresArray"
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
local self = _class_0
|
||||
self.__base.pgmoon_serialize = function(v, pg)
|
||||
local escaped
|
||||
do
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 1
|
||||
for _index_0 = 1, #v do
|
||||
local val = v[_index_0]
|
||||
if val == pg.NULL then
|
||||
_accum_0[_len_0] = "NULL"
|
||||
else
|
||||
local _exp_0 = type(val)
|
||||
if "number" == _exp_0 then
|
||||
_accum_0[_len_0] = tostring(val)
|
||||
elseif "string" == _exp_0 then
|
||||
_accum_0[_len_0] = '"' .. val:gsub('"', [[\"]]) .. '"'
|
||||
elseif "boolean" == _exp_0 then
|
||||
_accum_0[_len_0] = val and "t" or "f"
|
||||
elseif "table" == _exp_0 then
|
||||
local _oid, _value
|
||||
do
|
||||
local v_mt = getmetatable(val)
|
||||
if v_mt then
|
||||
if v_mt.pgmoon_serialize then
|
||||
_oid, _value = v_mt.pgmoon_serialize(val, pg)
|
||||
end
|
||||
end
|
||||
end
|
||||
if _oid then
|
||||
if is_array(_oid) then
|
||||
_accum_0[_len_0] = _value
|
||||
else
|
||||
_accum_0[_len_0] = '"' .. _value:gsub('"', [[\"]]) .. '"'
|
||||
end
|
||||
else
|
||||
return nil, "table does not implement pgmoon_serialize, can't serialize"
|
||||
end
|
||||
end
|
||||
end
|
||||
_len_0 = _len_0 + 1
|
||||
end
|
||||
escaped = _accum_0
|
||||
end
|
||||
local type_oid = 0
|
||||
for _index_0 = 1, #v do
|
||||
local _continue_0 = false
|
||||
repeat
|
||||
do
|
||||
local val = v[_index_0]
|
||||
if val == pg.NULL then
|
||||
_continue_0 = true
|
||||
break
|
||||
end
|
||||
type_oid = OIDS[type(val)] or type_oid
|
||||
break
|
||||
end
|
||||
_continue_0 = true
|
||||
until true
|
||||
if not _continue_0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
return type_oid, "{" .. tostring(table.concat(escaped, ",")) .. "}"
|
||||
end
|
||||
PostgresArray = _class_0
|
||||
end
|
||||
getmetatable(PostgresArray).__call = function(self, t)
|
||||
return setmetatable(t, self.__base)
|
||||
end
|
||||
local default_escape_literal = nil
|
||||
local insert, concat
|
||||
do
|
||||
local _obj_0 = table
|
||||
insert, concat = _obj_0.insert, _obj_0.concat
|
||||
end
|
||||
local encode_array
|
||||
do
|
||||
local append_buffer
|
||||
append_buffer = function(escape_literal, buffer, values)
|
||||
for _index_0 = 1, #values do
|
||||
local item = values[_index_0]
|
||||
if type(item) == "table" and not getmetatable(item) then
|
||||
insert(buffer, "[")
|
||||
append_buffer(escape_literal, buffer, item)
|
||||
buffer[#buffer] = "]"
|
||||
insert(buffer, ",")
|
||||
else
|
||||
insert(buffer, escape_literal(item))
|
||||
insert(buffer, ",")
|
||||
end
|
||||
end
|
||||
return buffer
|
||||
end
|
||||
encode_array = function(tbl, escape_literal)
|
||||
escape_literal = escape_literal or default_escape_literal
|
||||
if not (escape_literal) then
|
||||
local Postgres
|
||||
Postgres = require("pgmoon").Postgres
|
||||
default_escape_literal = function(v)
|
||||
return Postgres.escape_literal(nil, v)
|
||||
end
|
||||
escape_literal = default_escape_literal
|
||||
end
|
||||
local buffer = append_buffer(escape_literal, {
|
||||
"ARRAY["
|
||||
}, tbl)
|
||||
if buffer[#buffer] == "," then
|
||||
buffer[#buffer] = "]"
|
||||
else
|
||||
insert(buffer, "]")
|
||||
end
|
||||
return concat(buffer)
|
||||
end
|
||||
end
|
||||
local convert_values
|
||||
convert_values = function(array, fn, pg)
|
||||
for idx, v in ipairs(array) do
|
||||
if type(v) == "table" then
|
||||
convert_values(v, fn)
|
||||
else
|
||||
if v == "NULL" then
|
||||
array[idx] = pg.NULL
|
||||
elseif fn then
|
||||
array[idx] = fn(v)
|
||||
else
|
||||
array[idx] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
return array
|
||||
end
|
||||
local decode_array
|
||||
do
|
||||
local P, R, S, V, Ct, C, Cs
|
||||
do
|
||||
local _obj_0 = require("lpeg")
|
||||
P, R, S, V, Ct, C, Cs = _obj_0.P, _obj_0.R, _obj_0.S, _obj_0.V, _obj_0.Ct, _obj_0.C, _obj_0.Cs
|
||||
end
|
||||
local g = P({
|
||||
"array",
|
||||
array = Ct(V("open") * (V("value") * (P(",") * V("value")) ^ 0) ^ -1 * V("close")),
|
||||
value = V("invalid_char") + V("string") + V("array") + V("literal"),
|
||||
string = P('"') * Cs((P([[\\]]) / [[\]] + P([[\"]]) / [["]] + (P(1) - P('"'))) ^ 0) * P('"'),
|
||||
literal = C((P(1) - S("},")) ^ 1),
|
||||
invalid_char = S(" \t\r\n") / function()
|
||||
return error("got unexpected whitespace")
|
||||
end,
|
||||
open = P("{"),
|
||||
delim = P(","),
|
||||
close = P("}")
|
||||
})
|
||||
decode_array = function(str, convert_fn, pg)
|
||||
local out = (assert(g:match(str), "failed to parse postgresql array"))
|
||||
setmetatable(out, PostgresArray.__base)
|
||||
return convert_values(out, convert_fn, (pg or require("pgmoon").Postgres))
|
||||
end
|
||||
end
|
||||
return {
|
||||
encode_array = encode_array,
|
||||
decode_array = decode_array,
|
||||
PostgresArray = PostgresArray
|
||||
}
|
67
src/share/pgmoon/bit.lua
Normal file
67
src/share/pgmoon/bit.lua
Normal file
|
@ -0,0 +1,67 @@
|
|||
local rshift, lshift, band, bxor
|
||||
local load_code
|
||||
load_code = function(str)
|
||||
local sent = false
|
||||
return pcall(load(function()
|
||||
if sent then
|
||||
return nil
|
||||
end
|
||||
sent = true
|
||||
return str
|
||||
end))
|
||||
end
|
||||
local ok
|
||||
ok, band = load_code([[ return function(a,b)
|
||||
a = a & b
|
||||
if a > 0x7FFFFFFF then
|
||||
-- extend the sign bit
|
||||
a = ~0xFFFFFFFF | a
|
||||
end
|
||||
return a
|
||||
end
|
||||
]])
|
||||
if ok then
|
||||
local _
|
||||
_, bxor = load_code([[ return function(a,b)
|
||||
a = a ~ b
|
||||
if a > 0x7FFFFFFF then
|
||||
-- extend the sign bit
|
||||
a = ~0xFFFFFFFF | a
|
||||
end
|
||||
return a
|
||||
end
|
||||
]])
|
||||
_, lshift = load_code([[ return function(x,y)
|
||||
-- limit to 32-bit shifts
|
||||
y = y % 32
|
||||
x = x << y
|
||||
if x > 0x7FFFFFFF then
|
||||
-- extend the sign bit
|
||||
x = ~0xFFFFFFFF | x
|
||||
end
|
||||
return x
|
||||
end
|
||||
]])
|
||||
_, rshift = load_code([[ return function(x,y)
|
||||
y = y % 32
|
||||
-- truncate to 32-bit before applying shift
|
||||
x = x & 0xFFFFFFFF
|
||||
x = x >> y
|
||||
if x > 0x7FFFFFFF then
|
||||
x = ~0xFFFFFFFF | x
|
||||
end
|
||||
return x
|
||||
end
|
||||
]])
|
||||
else
|
||||
do
|
||||
local _obj_0 = require("bit")
|
||||
rshift, lshift, band, bxor = _obj_0.rshift, _obj_0.lshift, _obj_0.band, _obj_0.bxor
|
||||
end
|
||||
end
|
||||
return {
|
||||
rshift = rshift,
|
||||
lshift = lshift,
|
||||
band = band,
|
||||
bxor = bxor
|
||||
}
|
75
src/share/pgmoon/cqueues.lua
Normal file
75
src/share/pgmoon/cqueues.lua
Normal file
|
@ -0,0 +1,75 @@
|
|||
local flatten
|
||||
flatten = require("pgmoon.util").flatten
|
||||
local CqueuesSocket
|
||||
do
|
||||
local _class_0
|
||||
local _base_0 = {
|
||||
connect = function(self, host, port, opts)
|
||||
local socket = require("cqueues.socket")
|
||||
local errno = require("cqueues.errno")
|
||||
self.sock = socket.connect({
|
||||
host = host,
|
||||
port = port
|
||||
})
|
||||
if self.timeout then
|
||||
self.sock:settimeout(self.timeout)
|
||||
end
|
||||
self.sock:setmode("bn", "bn")
|
||||
local success, err = self.sock:connect()
|
||||
if not (success) then
|
||||
return nil, errno.strerror(err)
|
||||
end
|
||||
return true
|
||||
end,
|
||||
starttls = function(self, ...)
|
||||
return self.sock:starttls(...)
|
||||
end,
|
||||
getpeercertificate = function(self)
|
||||
local ssl = assert(self.sock:checktls())
|
||||
return assert(ssl:getPeerCertificate(), "no peer certificate available")
|
||||
end,
|
||||
send = function(self, ...)
|
||||
return self.sock:write(flatten(...))
|
||||
end,
|
||||
receive = function(self, ...)
|
||||
return self.sock:read(...)
|
||||
end,
|
||||
close = function(self)
|
||||
return self.sock:close()
|
||||
end,
|
||||
settimeout = function(self, t)
|
||||
if t then
|
||||
t = t / 1000
|
||||
end
|
||||
if self.sock then
|
||||
return self.sock:settimeout(t)
|
||||
else
|
||||
self.timeout = t
|
||||
end
|
||||
end,
|
||||
getreusedtimes = function(self)
|
||||
return 0
|
||||
end,
|
||||
setkeepalive = function(self)
|
||||
return error("You attempted to call setkeepalive on a cqueues.socket. This method is only available for the ngx cosocket API for releasing a socket back into the connection pool")
|
||||
end
|
||||
}
|
||||
_base_0.__index = _base_0
|
||||
_class_0 = setmetatable({
|
||||
__init = function() end,
|
||||
__base = _base_0,
|
||||
__name = "CqueuesSocket"
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
CqueuesSocket = _class_0
|
||||
end
|
||||
return {
|
||||
CqueuesSocket = CqueuesSocket
|
||||
}
|
178
src/share/pgmoon/crypto.lua
Normal file
178
src/share/pgmoon/crypto.lua
Normal file
|
@ -0,0 +1,178 @@
|
|||
local md5
|
||||
if ngx then
|
||||
md5 = ngx.md5
|
||||
elseif pcall(function()
|
||||
return require("openssl.digest")
|
||||
end) then
|
||||
local openssl_digest = require("openssl.digest")
|
||||
local hex_char
|
||||
hex_char = function(c)
|
||||
return string.format("%02x", string.byte(c))
|
||||
end
|
||||
local hex
|
||||
hex = function(str)
|
||||
return (str:gsub(".", hex_char))
|
||||
end
|
||||
md5 = function(str)
|
||||
return hex(openssl_digest.new("md5"):final(str))
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("crypto")
|
||||
end) then
|
||||
local crypto = require("crypto")
|
||||
md5 = function(str)
|
||||
return crypto.digest("md5", str)
|
||||
end
|
||||
else
|
||||
md5 = function()
|
||||
return error("Either luaossl (recommended) or LuaCrypto is required to calculate md5")
|
||||
end
|
||||
end
|
||||
local hmac_sha256
|
||||
if pcall(function()
|
||||
return require("openssl.hmac")
|
||||
end) then
|
||||
hmac_sha256 = function(key, str)
|
||||
local openssl_hmac = require("openssl.hmac")
|
||||
local hmac = assert(openssl_hmac.new(key, "sha256"))
|
||||
hmac:update(str)
|
||||
return assert(hmac:final())
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("resty.openssl.hmac")
|
||||
end) then
|
||||
hmac_sha256 = function(key, str)
|
||||
local openssl_hmac = require("resty.openssl.hmac")
|
||||
local hmac = assert(openssl_hmac.new(key, "sha256"))
|
||||
hmac:update(str)
|
||||
return assert(hmac:final())
|
||||
end
|
||||
else
|
||||
hmac_sha256 = function()
|
||||
return error("Either luaossl or resty.openssl is required to calculate hmac sha256 digest")
|
||||
end
|
||||
end
|
||||
local digest_sha256
|
||||
if pcall(function()
|
||||
return require("openssl.digest")
|
||||
end) then
|
||||
digest_sha256 = function(str)
|
||||
local digest = assert(require("openssl.digest").new("sha256"))
|
||||
digest:update(str)
|
||||
return assert(digest:final())
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("resty.sha256")
|
||||
end) then
|
||||
digest_sha256 = function(str)
|
||||
local digest = assert(require("resty.sha256"):new())
|
||||
digest:update(str)
|
||||
return assert(digest:final())
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("resty.openssl.digest")
|
||||
end) then
|
||||
digest_sha256 = function(str)
|
||||
local digest = assert(require("resty.openssl.digest").new("sha256"))
|
||||
digest:update(str)
|
||||
return assert(digest:final())
|
||||
end
|
||||
else
|
||||
digest_sha256 = function()
|
||||
return error("Either luaossl or resty.openssl is required to calculate sha256 digest")
|
||||
end
|
||||
end
|
||||
local kdf_derive_sha256
|
||||
if pcall(function()
|
||||
return require("openssl.kdf")
|
||||
end) then
|
||||
kdf_derive_sha256 = function(str, salt, i)
|
||||
local openssl_kdf = require("openssl.kdf")
|
||||
local decode_base64
|
||||
decode_base64 = require("pgmoon.util").decode_base64
|
||||
salt = decode_base64(salt)
|
||||
local key, err = openssl_kdf.derive({
|
||||
type = "PBKDF2",
|
||||
md = "sha256",
|
||||
salt = salt,
|
||||
iter = i,
|
||||
pass = str,
|
||||
outlen = 32
|
||||
})
|
||||
if not (key) then
|
||||
return nil, "failed to derive pbkdf2 key: " .. tostring(err)
|
||||
end
|
||||
return key
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("resty.openssl.kdf")
|
||||
end) then
|
||||
kdf_derive_sha256 = function(str, salt, i)
|
||||
local openssl_kdf = require("resty.openssl.kdf")
|
||||
local decode_base64
|
||||
decode_base64 = require("pgmoon.util").decode_base64
|
||||
salt = decode_base64(salt)
|
||||
local key, err = openssl_kdf.derive({
|
||||
type = openssl_kdf.PBKDF2,
|
||||
md = "sha256",
|
||||
salt = salt,
|
||||
pbkdf2_iter = i,
|
||||
pass = str,
|
||||
outlen = 32
|
||||
})
|
||||
if not (key) then
|
||||
return nil, "failed to derive pbkdf2 key: " .. tostring(err)
|
||||
end
|
||||
return key
|
||||
end
|
||||
else
|
||||
kdf_derive_sha256 = function()
|
||||
return error("Either luaossl or resty.openssl is required to derive pbkdf2 key")
|
||||
end
|
||||
end
|
||||
local random_bytes
|
||||
if pcall(function()
|
||||
return require("openssl.rand")
|
||||
end) then
|
||||
random_bytes = require("openssl.rand").bytes
|
||||
elseif pcall(function()
|
||||
return require("resty.random")
|
||||
end) then
|
||||
random_bytes = require("resty.random").bytes
|
||||
elseif pcall(function()
|
||||
return require("resty.openssl.rand")
|
||||
end) then
|
||||
random_bytes = require("resty.openssl.rand").bytes
|
||||
else
|
||||
random_bytes = function()
|
||||
return error("Either luaossl or resty.openssl is required to generate random bytes")
|
||||
end
|
||||
end
|
||||
local x509_digest
|
||||
if pcall(function()
|
||||
return require("openssl.x509")
|
||||
end) then
|
||||
local x509 = require("openssl.x509")
|
||||
x509_digest = function(pem, hash_type)
|
||||
return x509.new(pem, "PEM"):digest(hash_type, "s")
|
||||
end
|
||||
elseif pcall(function()
|
||||
return require("resty.openssl.x509")
|
||||
end) then
|
||||
local x509 = require("resty.openssl.x509")
|
||||
x509_digest = function(pem, hash_type)
|
||||
return x509.new(pem, "PEM"):digest(hash_type)
|
||||
end
|
||||
else
|
||||
x509_digest = function()
|
||||
return error("Either luaossl or resty.openssl is required to calculate x509 digest")
|
||||
end
|
||||
end
|
||||
return {
|
||||
md5 = md5,
|
||||
hmac_sha256 = hmac_sha256,
|
||||
digest_sha256 = digest_sha256,
|
||||
kdf_derive_sha256 = kdf_derive_sha256,
|
||||
random_bytes = random_bytes,
|
||||
x509_digest = x509_digest
|
||||
}
|
72
src/share/pgmoon/hstore.lua
Normal file
72
src/share/pgmoon/hstore.lua
Normal file
|
@ -0,0 +1,72 @@
|
|||
local PostgresHstore
|
||||
do
|
||||
local _class_0
|
||||
local _base_0 = { }
|
||||
_base_0.__index = _base_0
|
||||
_class_0 = setmetatable({
|
||||
__init = function() end,
|
||||
__base = _base_0,
|
||||
__name = "PostgresHstore"
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
PostgresHstore = _class_0
|
||||
end
|
||||
getmetatable(PostgresHstore).__call = function(self, t)
|
||||
return setmetatable(t, self.__base)
|
||||
end
|
||||
local encode_hstore
|
||||
do
|
||||
encode_hstore = function(tbl, escape_literal)
|
||||
if not (escape_literal) then
|
||||
local Postgres
|
||||
Postgres = require("pgmoon").Postgres
|
||||
local default_escape_literal
|
||||
default_escape_literal = function(v)
|
||||
return Postgres.escape_literal(nil, v)
|
||||
end
|
||||
escape_literal = default_escape_literal
|
||||
end
|
||||
local buffer = { }
|
||||
for k, v in pairs(tbl) do
|
||||
table.insert(buffer, '"' .. k .. '"=>"' .. v .. '"')
|
||||
end
|
||||
return escape_literal(table.concat(buffer, ", "))
|
||||
end
|
||||
end
|
||||
local decode_hstore
|
||||
do
|
||||
local P, R, S, V, Ct, C, Cs, Cg, Cf
|
||||
do
|
||||
local _obj_0 = require("lpeg")
|
||||
P, R, S, V, Ct, C, Cs, Cg, Cf = _obj_0.P, _obj_0.R, _obj_0.S, _obj_0.V, _obj_0.Ct, _obj_0.C, _obj_0.Cs, _obj_0.Cg, _obj_0.Cf
|
||||
end
|
||||
local g = P({
|
||||
"hstore",
|
||||
hstore = Cf(Ct("") * (V("pair") * (V("delim") * V("pair")) ^ 0) ^ -1, rawset) * -1,
|
||||
pair = Cg(V("value") * "=>" * (V("value") + V("null"))),
|
||||
value = V("invalid_char") + V("string"),
|
||||
string = P('"') * Cs((P([[\\]]) / [[\]] + P([[\"]]) / [["]] + (P(1) - P('"'))) ^ 0) * P('"'),
|
||||
null = C('NULL'),
|
||||
invalid_char = S(" \t\r\n") / function()
|
||||
return error("got unexpected whitespace")
|
||||
end,
|
||||
delim = P(", ")
|
||||
})
|
||||
decode_hstore = function(str, convert_fn)
|
||||
local out = (assert(g:match(str), "failed to parse postgresql hstore"))
|
||||
setmetatable(out, PostgresHstore.__base)
|
||||
return out
|
||||
end
|
||||
end
|
||||
return {
|
||||
encode_hstore = encode_hstore,
|
||||
decode_hstore = decode_hstore,
|
||||
PostgresHstore = PostgresHstore
|
||||
}
|
1118
src/share/pgmoon/init.lua
Normal file
1118
src/share/pgmoon/init.lua
Normal file
File diff suppressed because it is too large
Load Diff
25
src/share/pgmoon/json.lua
Normal file
25
src/share/pgmoon/json.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
local default_escape_literal = nil
|
||||
local encode_json
|
||||
encode_json = function(tbl, escape_literal)
|
||||
escape_literal = escape_literal or default_escape_literal
|
||||
local json = require("cjson")
|
||||
if not (escape_literal) then
|
||||
local Postgres
|
||||
Postgres = require("pgmoon").Postgres
|
||||
default_escape_literal = function(v)
|
||||
return Postgres.escape_literal(nil, v)
|
||||
end
|
||||
escape_literal = default_escape_literal
|
||||
end
|
||||
local enc = json.encode(tbl)
|
||||
return escape_literal(enc)
|
||||
end
|
||||
local decode_json
|
||||
decode_json = function(str)
|
||||
local json = require("cjson")
|
||||
return json.decode(str)
|
||||
end
|
||||
return {
|
||||
encode_json = encode_json,
|
||||
decode_json = decode_json
|
||||
}
|
109
src/share/pgmoon/socket.lua
Normal file
109
src/share/pgmoon/socket.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
local create_luasocket
|
||||
do
|
||||
local flatten
|
||||
flatten = require("pgmoon.util").flatten
|
||||
local proxy_mt = {
|
||||
__index = function(self, key)
|
||||
local sock = self.sock
|
||||
local original = sock[key]
|
||||
if type(original) == "function" then
|
||||
local fn
|
||||
fn = function(_, ...)
|
||||
return original(sock, ...)
|
||||
end
|
||||
self[key] = fn
|
||||
return fn
|
||||
else
|
||||
return original
|
||||
end
|
||||
end
|
||||
}
|
||||
local method_overrides
|
||||
method_overrides = {
|
||||
send = function(self, ...)
|
||||
return self.sock:send(flatten(...))
|
||||
end,
|
||||
settimeout = function(self, t)
|
||||
if t then
|
||||
t = t / 1000
|
||||
end
|
||||
return self.sock:settimeout(t)
|
||||
end,
|
||||
setkeepalive = function(self)
|
||||
return error("You attempted to call setkeepalive on a LuaSocket socket. This method is only available for the ngx cosocket API for releasing a socket back into the connection pool")
|
||||
end,
|
||||
getreusedtimes = function(self, t)
|
||||
return 0
|
||||
end,
|
||||
sslhandshake = function(self, opts)
|
||||
if opts == nil then
|
||||
opts = { }
|
||||
end
|
||||
local ssl = require("ssl")
|
||||
local params = {
|
||||
mode = "client",
|
||||
protocol = "any",
|
||||
verify = "none",
|
||||
options = {
|
||||
"all",
|
||||
"no_sslv2",
|
||||
"no_sslv3",
|
||||
"no_tlsv1"
|
||||
}
|
||||
}
|
||||
for k, v in pairs(opts) do
|
||||
params[k] = v
|
||||
end
|
||||
local sec_sock, err = ssl.wrap(self.sock, params)
|
||||
if not (sec_sock) then
|
||||
return false, err
|
||||
end
|
||||
local success
|
||||
success, err = sec_sock:dohandshake()
|
||||
if not (success) then
|
||||
return false, err
|
||||
end
|
||||
for k, v in pairs(self) do
|
||||
if not method_overrides[k] and type(v) == "function" then
|
||||
self[k] = nil
|
||||
end
|
||||
end
|
||||
self.sock = sec_sock
|
||||
return true
|
||||
end
|
||||
}
|
||||
create_luasocket = function(...)
|
||||
local socket = require("socket")
|
||||
local proxy = {
|
||||
sock = socket.tcp(...)
|
||||
}
|
||||
for k, v in pairs(method_overrides) do
|
||||
proxy[k] = v
|
||||
end
|
||||
return setmetatable(proxy, proxy_mt)
|
||||
end
|
||||
end
|
||||
return {
|
||||
create_luasocket = create_luasocket,
|
||||
new = function(socket_type)
|
||||
if socket_type == nil then
|
||||
if ngx and ngx.get_phase() ~= "init" then
|
||||
socket_type = "nginx"
|
||||
else
|
||||
socket_type = "luasocket"
|
||||
end
|
||||
end
|
||||
local socket
|
||||
local _exp_0 = socket_type
|
||||
if "nginx" == _exp_0 then
|
||||
socket = ngx.socket.tcp()
|
||||
elseif "luasocket" == _exp_0 then
|
||||
socket = create_luasocket()
|
||||
elseif "cqueues" == _exp_0 then
|
||||
socket = require("pgmoon.cqueues").CqueuesSocket()
|
||||
else
|
||||
socket = error("got unknown or unset socket type: " .. tostring(socket_type))
|
||||
end
|
||||
return socket, socket_type
|
||||
end
|
||||
}
|
46
src/share/pgmoon/util.lua
Normal file
46
src/share/pgmoon/util.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
local flatten
|
||||
do
|
||||
local __flatten
|
||||
__flatten = function(t, buffer)
|
||||
local _exp_0 = type(t)
|
||||
if "string" == _exp_0 then
|
||||
buffer[#buffer + 1] = t
|
||||
elseif "number" == _exp_0 then
|
||||
buffer[#buffer + 1] = tostring(t)
|
||||
elseif "table" == _exp_0 then
|
||||
for _index_0 = 1, #t do
|
||||
local thing = t[_index_0]
|
||||
__flatten(thing, buffer)
|
||||
end
|
||||
end
|
||||
end
|
||||
flatten = function(t)
|
||||
local buffer = { }
|
||||
__flatten(t, buffer)
|
||||
return table.concat(buffer)
|
||||
end
|
||||
end
|
||||
local encode_base64, decode_base64
|
||||
if ngx then
|
||||
do
|
||||
local _obj_0 = ngx
|
||||
encode_base64, decode_base64 = _obj_0.encode_base64, _obj_0.decode_base64
|
||||
end
|
||||
else
|
||||
local b64, unb64
|
||||
do
|
||||
local _obj_0 = require("mime")
|
||||
b64, unb64 = _obj_0.b64, _obj_0.unb64
|
||||
end
|
||||
encode_base64 = function(...)
|
||||
return (b64(...))
|
||||
end
|
||||
decode_base64 = function(...)
|
||||
return (unb64(...))
|
||||
end
|
||||
end
|
||||
return {
|
||||
flatten = flatten,
|
||||
encode_base64 = encode_base64,
|
||||
decode_base64 = decode_base64
|
||||
}
|
62
src/share/redis.lua
Normal file
62
src/share/redis.lua
Normal file
|
@ -0,0 +1,62 @@
|
|||
local redis = require("loadlib.resty_redis")
|
||||
local db_config = require('config.database')
|
||||
|
||||
local _M = setmetatable({}, {__index=function(self, key)
|
||||
local red = redis:new()
|
||||
local ok,err = red:connect(db_config.redis.host, db_config.redis.port)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR, err)
|
||||
end
|
||||
if key == 'red' then
|
||||
return red
|
||||
end
|
||||
end})
|
||||
|
||||
function _M:set(key, value, time)
|
||||
local ok, err = self.red:set(key, value)
|
||||
if not ok then
|
||||
return false, "redis failed to set data: " .. err
|
||||
end
|
||||
if time then
|
||||
ok,err = self.red:expire(key, time) -- default expire time is seconds
|
||||
if not ok then
|
||||
return false,err
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M:get(key)
|
||||
local value = self.red:get(key)
|
||||
if value == ngx.null then
|
||||
return nil
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
function _M:del(key)
|
||||
return self.red:del(key)
|
||||
end
|
||||
|
||||
function _M:expire(key, time)
|
||||
local ok,err = self.red:expire(key, time) -- default time is seconds
|
||||
if not ok then
|
||||
return false,err
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M:incr(key)
|
||||
local ok,err = self.red:incr(key)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M:ttl(key)
|
||||
return self.red:ttl(key)
|
||||
end
|
||||
|
||||
return _M
|
410
src/share/resty_redis.lua
Normal file
410
src/share/resty_redis.lua
Normal file
|
@ -0,0 +1,410 @@
|
|||
-- Copyright (C)
|
||||
|
||||
local sub = string.sub
|
||||
local byte = string.byte
|
||||
local tcp = ngx.socket.tcp
|
||||
local null = ngx.null
|
||||
local type = type
|
||||
local pairs = pairs
|
||||
local unpack = unpack
|
||||
local setmetatable = setmetatable
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local rawget = rawget
|
||||
--local error = error
|
||||
|
||||
local ok, new_tab = pcall(require, "table.new")
|
||||
if not ok or type(new_tab) ~= "function" then
|
||||
new_tab = function (narr, nrec) return {} end
|
||||
end
|
||||
|
||||
local _M = new_tab(0, 54)
|
||||
|
||||
_M._VERSION = '0.26'
|
||||
|
||||
local common_cmds = {
|
||||
"get", "set", "mget", "mset",
|
||||
"del", "incr", "decr", -- Strings
|
||||
"llen", "lindex", "lpop", "lpush",
|
||||
"lrange", "linsert", -- Lists
|
||||
"hexists", "hget", "hset", "hmget",
|
||||
--[[ "hmset", ]] "hdel", -- Hashes
|
||||
"smembers", "sismember", "sadd", "srem",
|
||||
"sdiff", "sinter", "sunion", -- Sets
|
||||
"zrange", "zrangebyscore", "zrank", "zadd",
|
||||
"zrem", "zincrby", -- Sorted Sets
|
||||
"auth", "eval", "expire", "script",
|
||||
"sort" -- Others
|
||||
}
|
||||
|
||||
local sub_commands = {
|
||||
"subscribe", "psubscribe"
|
||||
}
|
||||
|
||||
local unsub_commands = {
|
||||
"unsubscribe", "punsubscribe"
|
||||
}
|
||||
|
||||
local mt = { __index = _M }
|
||||
|
||||
function _M.new(self)
|
||||
local sock, err = tcp()
|
||||
if not sock then
|
||||
return nil, err
|
||||
end
|
||||
return setmetatable({ _sock = sock, _subscribed = false }, mt)
|
||||
end
|
||||
|
||||
function _M.set_timeout(self, timeout)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
return sock:settimeout(timeout)
|
||||
end
|
||||
|
||||
function _M.connect(self, ...)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
self._subscribed = false
|
||||
|
||||
return sock:connect(...)
|
||||
end
|
||||
|
||||
function _M.set_keepalive(self, ...)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
if rawget(self, "_subscribed") then
|
||||
return nil, "subscribed state"
|
||||
end
|
||||
|
||||
return sock:setkeepalive(...)
|
||||
end
|
||||
|
||||
function _M.get_reused_times(self)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
return sock:getreusedtimes()
|
||||
end
|
||||
|
||||
local function close(self)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
return sock:close()
|
||||
end
|
||||
_M.close = close
|
||||
|
||||
local function _read_reply(self, sock)
|
||||
local line, err = sock:receive()
|
||||
if not line then
|
||||
if err == "timeout" and not rawget(self, "_subscribed") then
|
||||
sock:close()
|
||||
end
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local prefix = byte(line)
|
||||
|
||||
if prefix == 36 then -- char '$'
|
||||
-- print("bulk reply")
|
||||
|
||||
local size = tonumber(sub(line, 2))
|
||||
if size < 0 then
|
||||
return null
|
||||
end
|
||||
|
||||
local data, err = sock:receive(size)
|
||||
if not data then
|
||||
if err == "timeout" then
|
||||
sock:close()
|
||||
end
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local dummy, err = sock:receive(2) -- ignore CRLF
|
||||
if not dummy then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return data
|
||||
|
||||
elseif prefix == 43 then -- char '+'
|
||||
-- print("status reply")
|
||||
|
||||
return sub(line, 2)
|
||||
|
||||
elseif prefix == 42 then -- char '*'
|
||||
local n = tonumber(sub(line, 2))
|
||||
|
||||
-- print("multi-bulk reply: ", n)
|
||||
if n < 0 then
|
||||
return null
|
||||
end
|
||||
|
||||
local vals = new_tab(n, 0)
|
||||
local nvals = 0
|
||||
for i = 1, n do
|
||||
local res, err = _read_reply(self, sock)
|
||||
if res then
|
||||
nvals = nvals + 1
|
||||
vals[nvals] = res
|
||||
|
||||
elseif res == nil then
|
||||
return nil, err
|
||||
|
||||
else
|
||||
-- be a valid redis error value
|
||||
nvals = nvals + 1
|
||||
vals[nvals] = {false, err}
|
||||
end
|
||||
end
|
||||
|
||||
return vals
|
||||
|
||||
elseif prefix == 58 then -- char ':'
|
||||
-- print("integer reply")
|
||||
return tonumber(sub(line, 2))
|
||||
|
||||
elseif prefix == 45 then -- char '-'
|
||||
-- print("error reply: ", n)
|
||||
|
||||
return false, sub(line, 2)
|
||||
|
||||
else
|
||||
-- when `line` is an empty string, `prefix` will be equal to nil.
|
||||
return nil, "unknown prefix: \"" .. tostring(prefix) .. "\""
|
||||
end
|
||||
end
|
||||
|
||||
local function _gen_req(args)
|
||||
local nargs = #args
|
||||
|
||||
local req = new_tab(nargs * 5 + 1, 0)
|
||||
req[1] = "*" .. nargs .. "\r\n"
|
||||
local nbits = 2
|
||||
|
||||
for i = 1, nargs do
|
||||
local arg = args[i]
|
||||
if type(arg) ~= "string" then
|
||||
arg = tostring(arg)
|
||||
end
|
||||
|
||||
req[nbits] = "$"
|
||||
req[nbits + 1] = #arg
|
||||
req[nbits + 2] = "\r\n"
|
||||
req[nbits + 3] = arg
|
||||
req[nbits + 4] = "\r\n"
|
||||
|
||||
nbits = nbits + 5
|
||||
end
|
||||
|
||||
-- it is much faster to do string concatenation on the C land
|
||||
-- in real world (large number of strings in the Lua VM)
|
||||
return req
|
||||
end
|
||||
|
||||
local function _do_cmd(self, ...)
|
||||
local args = {...}
|
||||
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
local req = _gen_req(args)
|
||||
|
||||
local reqs = rawget(self, "_reqs")
|
||||
if reqs then
|
||||
reqs[#reqs + 1] = req
|
||||
return
|
||||
end
|
||||
|
||||
-- print("request: ", table.concat(req))
|
||||
|
||||
local bytes, err = sock:send(req)
|
||||
if not bytes then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return _read_reply(self, sock)
|
||||
end
|
||||
|
||||
local function _check_subscribed(self, res)
|
||||
if type(res) == "table"
|
||||
and (res[1] == "unsubscribe" or res[1] == "punsubscribe")
|
||||
and res[3] == 0
|
||||
then
|
||||
self._subscribed = false
|
||||
end
|
||||
end
|
||||
|
||||
function _M.read_reply(self)
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
if not rawget(self, "_subscribed") then
|
||||
return nil, "not subscribed"
|
||||
end
|
||||
|
||||
local res, err = _read_reply(self, sock)
|
||||
_check_subscribed(self, res)
|
||||
|
||||
return res, err
|
||||
end
|
||||
|
||||
for i = 1, #common_cmds do
|
||||
local cmd = common_cmds[i]
|
||||
|
||||
_M[cmd] =
|
||||
function (self, ...)
|
||||
return _do_cmd(self, cmd, ...)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #sub_commands do
|
||||
local cmd = sub_commands[i]
|
||||
|
||||
_M[cmd] =
|
||||
function (self, ...)
|
||||
self._subscribed = true
|
||||
return _do_cmd(self, cmd, ...)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #unsub_commands do
|
||||
local cmd = unsub_commands[i]
|
||||
|
||||
_M[cmd] =
|
||||
function (self, ...)
|
||||
local res, err = _do_cmd(self, cmd, ...)
|
||||
_check_subscribed(self, res)
|
||||
return res, err
|
||||
end
|
||||
end
|
||||
|
||||
function _M.hmset(self, hashname, ...)
|
||||
if select('#', ...) == 1 then
|
||||
local t = select(1, ...)
|
||||
|
||||
local n = 0
|
||||
for k, v in pairs(t) do
|
||||
n = n + 2
|
||||
end
|
||||
|
||||
local array = new_tab(n, 0)
|
||||
|
||||
local i = 0
|
||||
for k, v in pairs(t) do
|
||||
array[i + 1] = k
|
||||
array[i + 2] = v
|
||||
i = i + 2
|
||||
end
|
||||
-- print("key", hashname)
|
||||
return _do_cmd(self, "hmset", hashname, unpack(array))
|
||||
end
|
||||
|
||||
-- backwards compatibility
|
||||
return _do_cmd(self, "hmset", hashname, ...)
|
||||
end
|
||||
|
||||
function _M.init_pipeline(self, n)
|
||||
self._reqs = new_tab(n or 4, 0)
|
||||
end
|
||||
|
||||
function _M.cancel_pipeline(self)
|
||||
self._reqs = nil
|
||||
end
|
||||
|
||||
function _M.commit_pipeline(self)
|
||||
local reqs = rawget(self, "_reqs")
|
||||
if not reqs then
|
||||
return nil, "no pipeline"
|
||||
end
|
||||
|
||||
self._reqs = nil
|
||||
|
||||
local sock = rawget(self, "_sock")
|
||||
if not sock then
|
||||
return nil, "not initialized"
|
||||
end
|
||||
|
||||
local bytes, err = sock:send(reqs)
|
||||
if not bytes then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local nvals = 0
|
||||
local nreqs = #reqs
|
||||
local vals = new_tab(nreqs, 0)
|
||||
for i = 1, nreqs do
|
||||
local res, err = _read_reply(self, sock)
|
||||
if res then
|
||||
nvals = nvals + 1
|
||||
vals[nvals] = res
|
||||
|
||||
elseif res == nil then
|
||||
if err == "timeout" then
|
||||
close(self)
|
||||
end
|
||||
return nil, err
|
||||
|
||||
else
|
||||
-- be a valid redis error value
|
||||
nvals = nvals + 1
|
||||
vals[nvals] = {false, err}
|
||||
end
|
||||
end
|
||||
|
||||
return vals
|
||||
end
|
||||
|
||||
function _M.array_to_hash(self, t)
|
||||
local n = #t
|
||||
-- print("n = ", n)
|
||||
local h = new_tab(0, n / 2)
|
||||
for i = 1, n, 2 do
|
||||
h[t[i]] = t[i + 1]
|
||||
end
|
||||
return h
|
||||
end
|
||||
|
||||
-- this method is deperate since we already do lazy method generation.
|
||||
function _M.add_commands(...)
|
||||
local cmds = {...}
|
||||
for i = 1, #cmds do
|
||||
local cmd = cmds[i]
|
||||
_M[cmd] =
|
||||
function (self, ...)
|
||||
return _do_cmd(self, cmd, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(_M, {__index = function(self, cmd)
|
||||
local method =
|
||||
function (self, ...)
|
||||
return _do_cmd(self, cmd, ...)
|
||||
end
|
||||
|
||||
-- cache the lazily generated method in our
|
||||
-- module table
|
||||
_M[cmd] = method
|
||||
return method
|
||||
end})
|
||||
|
||||
return _M
|
22
src/test.lua
Normal file
22
src/test.lua
Normal file
|
@ -0,0 +1,22 @@
|
|||
require("mobdebug").start("127.0.0.1")
|
||||
|
||||
--用于接收前端数据的对象
|
||||
local args = nil
|
||||
--获取前端的请求方式 并获取传递的参数
|
||||
local request_method = ngx.var.request_method
|
||||
--判断是get请求还是post请求并分别拿出相应的数据
|
||||
if "GET" == request_method then
|
||||
args = ngx.req.get_uri_args()
|
||||
elseif "POST" == request_method then
|
||||
ngx.req.read_body()
|
||||
args = ngx.req.get_post_args()
|
||||
--兼容请求使用post请求,但是传参以get方式传造成的无法获取到数据的bug
|
||||
if (args == nil or args.data == null) then
|
||||
args = ngx.req.get_uri_args()
|
||||
end
|
||||
end
|
||||
|
||||
--获取前端传递的name值
|
||||
local name = args.name
|
||||
--响应前端
|
||||
ngx.say("hello:"..name)
|
Loading…
Reference in New Issue
Block a user