Compare commits
No commits in common. "195800082a16d067f611313ea92527bcd9cd4e2c" and "ab6135e98adbc1498e6ec95e94e281a62f8b5da4" have entirely different histories.
195800082a
...
ab6135e98a
|
@ -186,6 +186,12 @@ func (s *Moonshark) initRunner() error {
|
||||||
runner.WithLibDirs(s.Config.Dirs.Libs...),
|
runner.WithLibDirs(s.Config.Dirs.Libs...),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add debug option conditionally
|
||||||
|
if s.Config.Server.Debug {
|
||||||
|
runnerOpts = append(runnerOpts, runner.WithDebugEnabled())
|
||||||
|
logger.Debug("Debug logging enabled for Lua runner")
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the runner
|
// Initialize the runner
|
||||||
var err error
|
var err error
|
||||||
s.LuaRunner, err = runner.NewRunner(runnerOpts...)
|
s.LuaRunner, err = runner.NewRunner(runnerOpts...)
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (s *Server) processRequest(ctx *fasthttp.RequestCtx) {
|
||||||
return
|
return
|
||||||
} else if found {
|
} else if found {
|
||||||
logger.Debug("Found Lua route match for %s %s with %d params", method, path, params.Count)
|
logger.Debug("Found Lua route match for %s %s with %d params", method, path, params.Count)
|
||||||
s.handleLuaRoute(ctx, bytecode, scriptPath, params, method, path)
|
s.handleLuaRoute(ctx, bytecode, scriptPath, params)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +152,13 @@ func (s *Server) processRequest(ctx *fasthttp.RequestCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleLuaRoute executes a Lua route
|
// handleLuaRoute executes a Lua route
|
||||||
func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scriptPath string, params *routers.Params, method string, path string) {
|
func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scriptPath string, params *routers.Params) {
|
||||||
// Create context for Lua execution
|
// Create context for Lua execution
|
||||||
luaCtx := runner.NewHTTPContext(ctx)
|
luaCtx := runner.NewHTTPContext(ctx)
|
||||||
defer luaCtx.Release()
|
defer luaCtx.Release()
|
||||||
|
|
||||||
|
method := string(ctx.Method())
|
||||||
|
path := string(ctx.Path())
|
||||||
host := string(ctx.Host())
|
host := string(ctx.Host())
|
||||||
|
|
||||||
// Set up additional context values
|
// Set up additional context values
|
||||||
|
@ -164,13 +166,6 @@ func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scrip
|
||||||
luaCtx.Set("path", path)
|
luaCtx.Set("path", path)
|
||||||
luaCtx.Set("host", host)
|
luaCtx.Set("host", host)
|
||||||
|
|
||||||
// Add session data
|
|
||||||
session := s.sessionManager.GetSessionFromRequest(ctx)
|
|
||||||
luaCtx.Set("session", map[string]any{
|
|
||||||
"id": session.ID,
|
|
||||||
"data": session.Data,
|
|
||||||
})
|
|
||||||
|
|
||||||
// URL parameters
|
// URL parameters
|
||||||
if params.Count > 0 {
|
if params.Count > 0 {
|
||||||
paramMap := make(map[string]any, params.Count)
|
paramMap := make(map[string]any, params.Count)
|
||||||
|
|
|
@ -44,20 +44,16 @@ func precompileSandboxCode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSandboxIntoState loads the sandbox code into a Lua state
|
// loadSandboxIntoState loads the sandbox code into a Lua state
|
||||||
func loadSandboxIntoState(state *luajit.State, verbose bool) error {
|
func loadSandboxIntoState(state *luajit.State) error {
|
||||||
bytecodeOnce.Do(precompileSandboxCode)
|
bytecodeOnce.Do(precompileSandboxCode)
|
||||||
|
|
||||||
bytecode := sandboxBytecode.Load()
|
bytecode := sandboxBytecode.Load()
|
||||||
if bytecode != nil && len(*bytecode) > 0 {
|
if bytecode != nil && len(*bytecode) > 0 {
|
||||||
if verbose {
|
logger.ServerCont("Loading sandbox.lua from precompiled bytecode") // piggyback off Sandbox.go's Setup()
|
||||||
logger.ServerCont("Loading sandbox.lua from precompiled bytecode") // piggyback off Sandbox.go's Setup()
|
|
||||||
}
|
|
||||||
return state.LoadAndRunBytecode(*bytecode, "sandbox.lua")
|
return state.LoadAndRunBytecode(*bytecode, "sandbox.lua")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to direct execution
|
// Fallback to direct execution
|
||||||
if verbose {
|
logger.WarningCont("Using non-precompiled sandbox.lua (bytecode compilation failed)")
|
||||||
logger.WarningCont("Using non-precompiled sandbox.lua (bytecode compilation failed)")
|
|
||||||
}
|
|
||||||
return state.DoString(sandboxLuaCode)
|
return state.DoString(sandboxLuaCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Moonshark/core/utils/logger"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -10,6 +9,8 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"Moonshark/core/utils/logger"
|
||||||
|
|
||||||
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ type Runner struct {
|
||||||
moduleLoader *ModuleLoader // Module loader
|
moduleLoader *ModuleLoader // Module loader
|
||||||
isRunning atomic.Bool // Whether the runner is active
|
isRunning atomic.Bool // Whether the runner is active
|
||||||
mu sync.RWMutex // Mutex for thread safety
|
mu sync.RWMutex // Mutex for thread safety
|
||||||
|
debug bool // Enable debug logging
|
||||||
scriptDir string // Current script directory
|
scriptDir string // Current script directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +54,13 @@ func WithPoolSize(size int) RunnerOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithDebugEnabled enables debug output
|
||||||
|
func WithDebugEnabled() RunnerOption {
|
||||||
|
return func(r *Runner) {
|
||||||
|
r.debug = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithLibDirs sets additional library directories
|
// WithLibDirs sets additional library directories
|
||||||
func WithLibDirs(dirs ...string) RunnerOption {
|
func WithLibDirs(dirs ...string) RunnerOption {
|
||||||
return func(r *Runner) {
|
return func(r *Runner) {
|
||||||
|
@ -70,6 +79,7 @@ func NewRunner(options ...RunnerOption) (*Runner, error) {
|
||||||
// Default configuration
|
// Default configuration
|
||||||
runner := &Runner{
|
runner := &Runner{
|
||||||
poolSize: runtime.GOMAXPROCS(0),
|
poolSize: runtime.GOMAXPROCS(0),
|
||||||
|
debug: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply options
|
// Apply options
|
||||||
|
@ -86,6 +96,11 @@ func NewRunner(options ...RunnerOption) (*Runner, error) {
|
||||||
runner.moduleLoader = NewModuleLoader(config)
|
runner.moduleLoader = NewModuleLoader(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable debug if requested
|
||||||
|
if runner.debug {
|
||||||
|
runner.moduleLoader.EnableDebug()
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize states and pool
|
// Initialize states and pool
|
||||||
runner.states = make([]*State, runner.poolSize)
|
runner.states = make([]*State, runner.poolSize)
|
||||||
runner.statePool = make(chan int, runner.poolSize)
|
runner.statePool = make(chan int, runner.poolSize)
|
||||||
|
@ -100,11 +115,19 @@ func NewRunner(options ...RunnerOption) (*Runner, error) {
|
||||||
return runner, nil
|
return runner, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debugLog logs a message if debug mode is enabled
|
||||||
|
func (r *Runner) debugLog(format string, args ...interface{}) {
|
||||||
|
if r.debug {
|
||||||
|
logger.Debug("Runner "+format, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// initializeStates creates and initializes all states in the pool
|
// initializeStates creates and initializes all states in the pool
|
||||||
func (r *Runner) initializeStates() error {
|
func (r *Runner) initializeStates() error {
|
||||||
logger.Server("Initializing %d states...", r.poolSize)
|
r.debugLog("Initializing %d states", r.poolSize)
|
||||||
|
|
||||||
for i := range r.poolSize {
|
// Create all states
|
||||||
|
for i := 0; i < r.poolSize; i++ {
|
||||||
state, err := r.createState(i)
|
state, err := r.createState(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -121,7 +144,7 @@ func (r *Runner) initializeStates() error {
|
||||||
func (r *Runner) createState(index int) (*State, error) {
|
func (r *Runner) createState(index int) (*State, error) {
|
||||||
verbose := index == 0
|
verbose := index == 0
|
||||||
if verbose {
|
if verbose {
|
||||||
logger.ServerCont("Creating Lua state %d", index)
|
r.debugLog("Creating Lua state %d", index)
|
||||||
}
|
}
|
||||||
|
|
||||||
L := luajit.New()
|
L := luajit.New()
|
||||||
|
@ -132,7 +155,7 @@ func (r *Runner) createState(index int) (*State, error) {
|
||||||
sb := NewSandbox()
|
sb := NewSandbox()
|
||||||
|
|
||||||
// Set up sandbox
|
// Set up sandbox
|
||||||
if err := sb.Setup(L, verbose); err != nil {
|
if err := sb.Setup(L); err != nil {
|
||||||
L.Cleanup()
|
L.Cleanup()
|
||||||
L.Close()
|
L.Close()
|
||||||
return nil, ErrInitFailed
|
return nil, ErrInitFailed
|
||||||
|
@ -153,7 +176,7 @@ func (r *Runner) createState(index int) (*State, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
logger.ServerCont("Lua state %d initialized successfully", index)
|
r.debugLog("Lua state %d initialized successfully", index)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &State{
|
return &State{
|
||||||
|
@ -258,7 +281,7 @@ cleanup:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("Runner closed")
|
r.debugLog("Runner closed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +294,7 @@ func (r *Runner) RefreshStates() error {
|
||||||
return ErrRunnerClosed
|
return ErrRunnerClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Server("Runner is refreshing all states...")
|
r.debugLog("Refreshing all states...")
|
||||||
|
|
||||||
// Drain all states from the pool
|
// Drain all states from the pool
|
||||||
for {
|
for {
|
||||||
|
@ -289,7 +312,7 @@ cleanup:
|
||||||
for i, state := range r.states {
|
for i, state := range r.states {
|
||||||
if state != nil {
|
if state != nil {
|
||||||
if state.inUse {
|
if state.inUse {
|
||||||
logger.WarningCont("Attempting to refresh state %d that is in use", i)
|
r.debugLog("Warning: attempting to refresh state %d that is in use", i)
|
||||||
}
|
}
|
||||||
state.L.Cleanup()
|
state.L.Cleanup()
|
||||||
state.L.Close()
|
state.L.Close()
|
||||||
|
@ -302,25 +325,24 @@ cleanup:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.ServerCont("All states refreshed successfully")
|
r.debugLog("All states refreshed successfully")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyFileChanged alerts the runner about file changes
|
// NotifyFileChanged alerts the runner about file changes
|
||||||
func (r *Runner) NotifyFileChanged(filePath string) bool {
|
func (r *Runner) NotifyFileChanged(filePath string) bool {
|
||||||
logger.Debug("Runner has been notified of a file change...")
|
r.debugLog("File change detected: %s", filePath)
|
||||||
logger.Debug("%s", filePath)
|
|
||||||
|
|
||||||
// Check if it's a module file
|
// Check if it's a module file
|
||||||
module, isModule := r.moduleLoader.GetModuleByPath(filePath)
|
module, isModule := r.moduleLoader.GetModuleByPath(filePath)
|
||||||
if isModule {
|
if isModule {
|
||||||
logger.DebugCont("File is a module: %s", module)
|
r.debugLog("File is a module: %s", module)
|
||||||
return r.RefreshModule(module)
|
return r.RefreshModule(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For non-module files, refresh all states
|
// For non-module files, refresh all states
|
||||||
if err := r.RefreshStates(); err != nil {
|
if err := r.RefreshStates(); err != nil {
|
||||||
logger.DebugCont("Failed to refresh states: %v", err)
|
r.debugLog("Failed to refresh states: %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +358,7 @@ func (r *Runner) RefreshModule(moduleName string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.DebugCont("Refreshing module: %s", moduleName)
|
r.debugLog("Refreshing module: %s", moduleName)
|
||||||
|
|
||||||
success := true
|
success := true
|
||||||
for _, state := range r.states {
|
for _, state := range r.states {
|
||||||
|
@ -347,7 +369,7 @@ func (r *Runner) RefreshModule(moduleName string) bool {
|
||||||
// Invalidate module in Lua
|
// Invalidate module in Lua
|
||||||
if err := state.L.DoString(`package.loaded["` + moduleName + `"] = nil`); err != nil {
|
if err := state.L.DoString(`package.loaded["` + moduleName + `"] = nil`); err != nil {
|
||||||
success = false
|
success = false
|
||||||
logger.DebugCont("Failed to invalidate module %s: %v", moduleName, err)
|
r.debugLog("Failed to invalidate module %s: %v", moduleName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,10 @@ func (s *Sandbox) AddModule(name string, module any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup initializes the sandbox in a Lua state
|
// Setup initializes the sandbox in a Lua state
|
||||||
func (s *Sandbox) Setup(state *luajit.State, verbose bool) error {
|
func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
if verbose {
|
logger.Server("Setting up sandbox...")
|
||||||
logger.Server("Setting up sandbox...")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := loadSandboxIntoState(state, verbose); err != nil {
|
if err := loadSandboxIntoState(state); err != nil {
|
||||||
logger.ErrorCont("Failed to load sandbox: %v", err)
|
logger.ErrorCont("Failed to load sandbox: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -76,9 +74,7 @@ func (s *Sandbox) Setup(state *luajit.State, verbose bool) error {
|
||||||
}
|
}
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
|
|
||||||
if verbose {
|
logger.ServerCont("Sandbox setup complete")
|
||||||
logger.ServerCont("Sandbox setup complete")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +135,19 @@ func (s *Sandbox) Execute(state *luajit.State, bytecode []byte, ctx *Context) (*
|
||||||
|
|
||||||
// extractResponseData pulls response info from the Lua state
|
// extractResponseData pulls response info from the Lua state
|
||||||
func extractHTTPResponseData(state *luajit.State, response *Response) {
|
func extractHTTPResponseData(state *luajit.State, response *Response) {
|
||||||
state.GetGlobal("__http_response")
|
state.GetGlobal("__http_responses")
|
||||||
if !state.IsTable(-1) {
|
if !state.IsTable(-1) {
|
||||||
state.Pop(1)
|
state.Pop(1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.PushNumber(1)
|
||||||
|
state.GetTable(-2)
|
||||||
|
if !state.IsTable(-1) {
|
||||||
|
state.Pop(2)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Extract status
|
// Extract status
|
||||||
state.GetField(-1, "status")
|
state.GetField(-1, "status")
|
||||||
if state.IsNumber(-1) {
|
if state.IsNumber(-1) {
|
||||||
|
@ -193,7 +196,8 @@ func extractHTTPResponseData(state *luajit.State, response *Response) {
|
||||||
}
|
}
|
||||||
state.Pop(1)
|
state.Pop(1)
|
||||||
|
|
||||||
state.Pop(1) // Pop __http_response
|
// Clean up
|
||||||
|
state.Pop(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractCookie pulls cookie data from the current table on the stack
|
// extractCookie pulls cookie data from the current table on the stack
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sessions
|
package sessions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"maps"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +66,9 @@ func (s *Session) GetAll() map[string]any {
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
copy := make(map[string]any, len(s.Data))
|
copy := make(map[string]any, len(s.Data))
|
||||||
maps.Copy(copy, s.Data)
|
for k, v := range s.Data {
|
||||||
|
copy[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
return copy
|
return copy
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user