diff --git a/core/Moonshark.go b/core/Moonshark.go index d4a103f..37e36c4 100644 --- a/core/Moonshark.go +++ b/core/Moonshark.go @@ -172,12 +172,12 @@ func (s *Moonshark) initRunner() error { // Configure session cookies sessionManager.SetCookieOptions( - "MSSESSID", // name - "/", // path - "", // domain - false, // secure - true, // httpOnly - 86400, // maxAge (1 day) + "MoonsharkID", // name + "/", // path + "", // domain + false, // secure + true, // httpOnly + 86400, // maxAge (1 day) ) // Set up runner options diff --git a/core/http/Server.go b/core/http/Server.go index fa23a49..4337e83 100644 --- a/core/http/Server.go +++ b/core/http/Server.go @@ -3,6 +3,7 @@ package http import ( "context" "fmt" + "strings" "time" "Moonshark/core/metadata" @@ -160,7 +161,7 @@ func HandleMethodNotAllowed(ctx *fasthttp.RequestCtx, errorConfig utils.ErrorPag // handleLuaRoute executes a Lua route func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scriptPath string, params *routers.Params) { - luaCtx := runner.NewContext() + luaCtx := runner.NewHTTPContext(ctx) // Use NewHTTPContext instead of NewContext defer luaCtx.Release() method := string(ctx.Method()) @@ -242,7 +243,10 @@ func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scrip return } - writeResponse(ctx, result) + // If we got a non-nil result, write it to the response + if result != nil { + writeResponse(ctx, result) + } } // Content types for responses @@ -258,34 +262,47 @@ func writeResponse(ctx *fasthttp.RequestCtx, result any) { return } - // Check for HTTPResponse type - if httpResp, ok := result.(*sandbox.HTTPResponse); ok { - defer sandbox.ReleaseResponse(httpResp) + // First check the raw type of the result for strong type identification + // Sometimes type assertions don't work as expected with interface values + resultType := fmt.Sprintf("%T", result) - // Set response headers - for name, value := range httpResp.Headers { - ctx.Response.Header.Set(name, value) - } + // Strong check for HTTP response + if strings.Contains(resultType, "HTTPResponse") || strings.Contains(resultType, "sandbox.HTTPResponse") { + httpResp, ok := result.(*sandbox.HTTPResponse) + if ok { + defer sandbox.ReleaseResponse(httpResp) - // Set cookies - for _, cookie := range httpResp.Cookies { - ctx.Response.Header.SetCookie(cookie) - } + // Set response headers + for name, value := range httpResp.Headers { + ctx.Response.Header.Set(name, value) + } - // Set status code - ctx.SetStatusCode(httpResp.Status) + // Set cookies + for _, cookie := range httpResp.Cookies { + ctx.Response.Header.SetCookie(cookie) + } - // Process the body based on its type - if httpResp.Body == nil { + // Set status code + ctx.SetStatusCode(httpResp.Status) + + // Process the body based on its type + if httpResp.Body == nil { + return + } + + // Continue with the body only + result = httpResp.Body + } else { + // We identified it as HTTPResponse but couldn't convert it + // This is a programming error + logger.Error("Found HTTPResponse type but failed to convert: %v", resultType) + ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError) return } - - result = httpResp.Body // Set result to body for processing below } // Check if it's a map (table) or array - return as JSON isJSON := false - switch result.(type) { case map[string]any, []any, []float64, []string, []int: isJSON = true @@ -303,18 +320,21 @@ func writeResponse(ctx *fasthttp.RequestCtx, result any) { return } - // All other types - convert to plain text - setContentTypeIfMissing(ctx, contentTypePlain) - + // Handle string and byte slice cases directly switch r := result.(type) { case string: + setContentTypeIfMissing(ctx, contentTypePlain) ctx.SetBodyString(r) + return case []byte: + setContentTypeIfMissing(ctx, contentTypePlain) ctx.SetBody(r) - default: - // Convert any other type to string - ctx.SetBodyString(fmt.Sprintf("%v", r)) + return } + + // If we reach here, it's an unexpected type - convert to string as a last resort + setContentTypeIfMissing(ctx, contentTypePlain) + ctx.SetBodyString(fmt.Sprintf("%v", result)) } func setContentTypeIfMissing(ctx *fasthttp.RequestCtx, contentType string) { diff --git a/core/runner/Runner.go b/core/runner/Runner.go index 0c5008d..e6eb010 100644 --- a/core/runner/Runner.go +++ b/core/runner/Runner.go @@ -3,7 +3,6 @@ package runner import ( "context" "errors" - "fmt" "path/filepath" "runtime" "sync" @@ -277,8 +276,21 @@ func (r *Runner) Execute(ctx context.Context, bytecode []byte, execCtx *Context, ctxValues = execCtx.Values } - // Execute in sandbox - result, err := state.sandbox.Execute(state.L, bytecode, ctxValues) + // Execute in sandbox with optimized context handling + var result any + var err error + + if execCtx != nil && execCtx.RequestCtx != nil { + // Use OptimizedExecute directly with the full context if we have RequestCtx + result, err = state.sandbox.OptimizedExecute(state.L, bytecode, &sandbox.Context{ + Values: ctxValues, + RequestCtx: execCtx.RequestCtx, + }) + } else { + // Otherwise use standard Execute with just values + result, err = state.sandbox.Execute(state.L, bytecode, ctxValues) + } + if err != nil { return nil, err } @@ -290,35 +302,24 @@ func (r *Runner) Execute(ctx context.Context, bytecode []byte, execCtx *Context, } } - // Check for HTTP response - httpResp, hasResponse := sandbox.GetHTTPResponse(state.L) - if hasResponse { - // Set result as body if not already set - if httpResp.Body == nil { - httpResp.Body = result - } + // Check for HTTP response if we don't have a RequestCtx or if we still have a result + if execCtx == nil || execCtx.RequestCtx == nil || result != nil { + httpResp, hasResponse := sandbox.GetHTTPResponse(state.L) + if hasResponse { + // Set result as body if not already set + if httpResp.Body == nil { + httpResp.Body = result + } - // Apply directly to request context if available - if execCtx != nil && execCtx.RequestCtx != nil { - sandbox.ApplyHTTPResponse(httpResp, execCtx.RequestCtx) - sandbox.ReleaseResponse(httpResp) - return nil, nil - } + // Apply directly to request context if available + if execCtx != nil && execCtx.RequestCtx != nil { + sandbox.ApplyHTTPResponse(httpResp, execCtx.RequestCtx) + sandbox.ReleaseResponse(httpResp) + return nil, nil + } - return httpResp, nil - } - - // Handle direct result if FastHTTP context is available - if execCtx != nil && execCtx.RequestCtx != nil && result != nil { - switch r := result.(type) { - case string: - execCtx.RequestCtx.SetBodyString(r) - case []byte: - execCtx.RequestCtx.SetBody(r) - default: - execCtx.RequestCtx.SetBodyString(fmt.Sprintf("%v", r)) + return httpResp, nil } - return nil, nil } return result, err diff --git a/core/sessions/Manager.go b/core/sessions/Manager.go index 7513b91..a035dab 100644 --- a/core/sessions/Manager.go +++ b/core/sessions/Manager.go @@ -13,7 +13,7 @@ import ( const ( // Default settings DefaultMaxSize = 100 * 1024 * 1024 // 100MB default cache size - DefaultCookieName = "MSESSID" + DefaultCookieName = "MoonsharkID" DefaultCookiePath = "/" DefaultMaxAge = 86400 // 1 day in seconds )