172 lines
3.3 KiB
Lua
172 lines
3.3 KiB
Lua
local get_phase = ngx.get_phase
|
|
local timer_at = ngx.timer.at
|
|
local kong = kong
|
|
|
|
|
|
local PK = {
|
|
id = "",
|
|
}
|
|
|
|
local TTL = {
|
|
ttl = 0,
|
|
}
|
|
|
|
local DATA = {
|
|
session_id = "",
|
|
data = "",
|
|
expires = 0,
|
|
}
|
|
|
|
local STALE_DATA = {
|
|
expires = 0,
|
|
}
|
|
|
|
|
|
local storage = {}
|
|
|
|
|
|
storage.__index = storage
|
|
|
|
|
|
local function load_session_from_db(key)
|
|
return kong.db.sessions:select_by_session_id(key)
|
|
end
|
|
|
|
|
|
local function load_session_from_cache(key)
|
|
local cache_key = kong.db.sessions:cache_key(key)
|
|
return kong.cache:get(cache_key, nil, load_session_from_db, key)
|
|
end
|
|
|
|
local function insert_session_metadata(metadata, session)
|
|
if not metadata then
|
|
return
|
|
end
|
|
|
|
local audiences = metadata.audiences
|
|
local subjects = metadata.subjects
|
|
local count = #audiences
|
|
for i = 1, count do
|
|
local _, err = kong.db.session_metadatas:insert({
|
|
sid = session.session_id,
|
|
audience = audiences[i],
|
|
subject = subjects[i],
|
|
session = session,
|
|
})
|
|
|
|
if err then
|
|
kong.db.sessions:delete(session.id)
|
|
return false, err
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function insert_session(key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
|
|
DATA.session_id = key
|
|
DATA.data = value
|
|
DATA.expires = current_time + ttl
|
|
|
|
TTL.ttl = ttl
|
|
|
|
local insert_ok, insert_err = kong.db.sessions:insert(DATA, TTL)
|
|
if not insert_err then
|
|
local ok, err = insert_session_metadata(metadata, insert_ok)
|
|
if not ok and err then
|
|
return nil, err
|
|
end
|
|
end
|
|
|
|
if not old_key then
|
|
return insert_ok, insert_err
|
|
end
|
|
|
|
local old_row, err = load_session_from_cache(old_key)
|
|
if err then
|
|
kong.log.notice(err)
|
|
|
|
elseif old_row then
|
|
PK.id = old_row.id
|
|
if remember then
|
|
local ok, err = kong.db.sessions:delete(PK)
|
|
if not ok then
|
|
if err then
|
|
kong.log.notice(err)
|
|
else
|
|
kong.log.notice("unable to delete session data")
|
|
end
|
|
end
|
|
|
|
else
|
|
STALE_DATA.expires = current_time + stale_ttl
|
|
TTL.ttl = stale_ttl
|
|
local ok, err = kong.db.sessions:update(PK, STALE_DATA, TTL)
|
|
if not ok then
|
|
if err then
|
|
kong.log.notice(err)
|
|
else
|
|
kong.log.notice("unable update session ttl")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return insert_ok, insert_err
|
|
end
|
|
|
|
|
|
local function insert_session_timer(premature, ...)
|
|
if premature then
|
|
return
|
|
end
|
|
|
|
local ok, err = insert_session(...)
|
|
if not ok then
|
|
if err then
|
|
kong.log.notice(err)
|
|
else
|
|
kong.log.warn("unable to insert session")
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function storage:set(name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
|
|
if get_phase() == "header_filter" then
|
|
timer_at(0, insert_session_timer, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
|
|
return true
|
|
end
|
|
|
|
return insert_session(key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
|
|
end
|
|
|
|
|
|
function storage:get(name, key, current_time)
|
|
if get_phase() == "header_filter" then
|
|
return
|
|
end
|
|
|
|
local row, err = load_session_from_cache(key)
|
|
if not row then
|
|
return nil, err
|
|
end
|
|
|
|
return row.data
|
|
end
|
|
|
|
|
|
function storage:delete(name, key, current_time, metadata)
|
|
local row, err = load_session_from_cache(key)
|
|
if not row then
|
|
return nil, err
|
|
end
|
|
|
|
PK.id = row.id
|
|
|
|
return kong.db.sessions:delete(PK)
|
|
end
|
|
|
|
|
|
return storage
|