diff --git a/core/http/Server.go b/core/http/Server.go index 9c3e514..f5a333b 100644 --- a/core/http/Server.go +++ b/core/http/Server.go @@ -210,6 +210,12 @@ func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scrip return } + // Handle persisting session data + for k, v := range response.SessionData { + session.Set(k, v) + } + s.sessionManager.ApplySessionCookie(ctx, session) + // Apply response to HTTP context runner.ApplyResponse(response, ctx) diff --git a/core/runner/Response.go b/core/runner/Response.go index b608ba5..751e554 100644 --- a/core/runner/Response.go +++ b/core/runner/Response.go @@ -18,9 +18,7 @@ type Response struct { Cookies []*fasthttp.Cookie // HTTP cookies // Session information - SessionID string // Session ID - SessionData map[string]any // Session data - SessionModified bool // Whether session was modified + SessionData map[string]any } // Response pool to reduce allocations @@ -47,30 +45,12 @@ func ReleaseResponse(resp *Response) { return } - // Reset fields to default values resp.Body = nil resp.Status = 200 - - // Clear maps - for k := range resp.Headers { - delete(resp.Headers, k) - } - - for k := range resp.Metadata { - delete(resp.Metadata, k) - } - - for k := range resp.SessionData { - delete(resp.SessionData, k) - } - - // Clear cookies + resp.Headers = make(map[string]string, 8) + resp.Metadata = make(map[string]any, 8) resp.Cookies = resp.Cookies[:0] + resp.SessionData = make(map[string]any, 8) - // Reset session info - resp.SessionID = "" - resp.SessionModified = false - - // Return to pool responsePool.Put(resp) } diff --git a/core/runner/Sandbox.go b/core/runner/Sandbox.go index 436d9df..8174123 100644 --- a/core/runner/Sandbox.go +++ b/core/runner/Sandbox.go @@ -193,6 +193,16 @@ func extractHTTPResponseData(state *luajit.State, response *Response) { } state.Pop(1) + // Extract session data + state.GetField(-1, "session") + if state.IsTable(-1) { + table, err := state.ToTable(-1) + if err == nil { + maps.Copy(response.SessionData, table) + } + } + state.Pop(1) + state.Pop(1) // Pop __http_response } diff --git a/core/runner/sandbox.lua b/core/runner/sandbox.lua index 2053ce4..2ab921d 100644 --- a/core/runner/sandbox.lua +++ b/core/runner/sandbox.lua @@ -261,6 +261,49 @@ local cookie = { end } +-- ====================================================================== +-- SESSION MODULE +-- ====================================================================== + +local session = { + get = function(key) + if type(key) ~= "string" then + error("session.get: key must be a string", 2) + end + + local env = getfenv(2) + + if env.ctx and env.ctx.session and env.ctx.session.data then + return env.ctx.session.data[key] + end + + return nil + end, + + set = function(key, value) + if type(key) ~= "string" then + error("session.set: key must be a string", 2) + end + if type(value) == nil then + error("session.set: value cannot be nil", 2) + end + + local resp = __ensure_response() + resp.session = resp.session or {} + resp.session[key] = value + end, + + id = function() + local env = getfenv(2) + + if env.ctx and env.ctx.session then + return env.ctx.session.id + end + + return nil + end +} + -- ====================================================================== -- UTIL MODULE -- ====================================================================== @@ -350,5 +393,6 @@ local util = { -- ====================================================================== _G.http = http +_G.session = session _G.cookie = cookie _G.util = util