Moonshark/core/runner/cookies.go

173 lines
4.2 KiB
Go

package runner
import (
"net/http"
"time"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
)
// extractCookie grabs cookies from the Lua state
func extractCookie(state *luajit.State) *http.Cookie {
cookie := &http.Cookie{
Path: "/", // Default path
}
// Get name
state.GetField(-1, "name")
if !state.IsString(-1) {
state.Pop(1)
return nil // Name is required
}
cookie.Name = state.ToString(-1)
state.Pop(1)
// Get value
state.GetField(-1, "value")
if state.IsString(-1) {
cookie.Value = state.ToString(-1)
}
state.Pop(1)
// Get path
state.GetField(-1, "path")
if state.IsString(-1) {
cookie.Path = state.ToString(-1)
}
state.Pop(1)
// Get domain
state.GetField(-1, "domain")
if state.IsString(-1) {
cookie.Domain = state.ToString(-1)
}
state.Pop(1)
// Get expires
state.GetField(-1, "expires")
if state.IsNumber(-1) {
expiry := int64(state.ToNumber(-1))
cookie.Expires = time.Unix(expiry, 0)
}
state.Pop(1)
// Get max age
state.GetField(-1, "max_age")
if state.IsNumber(-1) {
cookie.MaxAge = int(state.ToNumber(-1))
}
state.Pop(1)
// Get secure
state.GetField(-1, "secure")
if state.IsBoolean(-1) {
cookie.Secure = state.ToBoolean(-1)
}
state.Pop(1)
// Get http only
state.GetField(-1, "http_only")
if state.IsBoolean(-1) {
cookie.HttpOnly = state.ToBoolean(-1)
}
state.Pop(1)
return cookie
}
// LuaCookieModule provides cookie functionality to Lua scripts
const LuaCookieModule = `
-- Cookie module implementation
local cookie = {
-- Set a cookie
set = function(name, value, expires, path, domain, secure, http_only)
if type(name) ~= "string" then
error("cookie.set: name must be a string", 2)
end
-- Get or create response
local resp = __http_responses[1] or {}
resp.cookies = resp.cookies or {}
__http_responses[1] = resp
-- Create cookie table
local cookie = {
name = name,
value = value or "",
path = path or "/",
domain = domain
}
-- Handle expiry
if expires then
if type(expires) == "number" then
if expires > 0 then
-- Add seconds to current time
cookie.max_age = expires
local now = os.time()
cookie.expires = now + expires
elseif expires < 0 then
-- Session cookie (default)
else
-- Expire immediately
cookie.expires = 0
cookie.max_age = 0
end
end
end
-- Set flags
cookie.secure = secure or false
cookie.http_only = http_only or false
-- Store in cookies table
local n = #resp.cookies + 1
resp.cookies[n] = cookie
return true
end,
-- Get a cookie value
get = function(name)
if type(name) ~= "string" then
error("cookie.get: name must be a string", 2)
end
-- Access values directly from current environment
local env = getfenv(1)
-- Check if context exists and has cookies
if env.ctx and env.ctx.cookies and env.ctx.cookies[name] then
return tostring(env.ctx.cookies[name])
end
return nil
end,
-- Remove a cookie
remove = function(name, path, domain)
if type(name) ~= "string" then
error("cookie.remove: name must be a string", 2)
end
-- Create an expired cookie
return cookie.set(name, "", 0, path or "/", domain, false, false)
end
}
-- Install cookie module
_G.cookie = cookie
-- Make sure the cookie module is accessible in sandbox
if __env_system and __env_system.base_env then
__env_system.base_env.cookie = cookie
end
`
// CookieModuleInitFunc returns an initializer for the cookie module
func CookieModuleInitFunc() StateInitFunc {
return func(state *luajit.State) error {
return state.DoString(LuaCookieModule)
}
}