http response fix

This commit is contained in:
Sky Johnson 2025-04-08 22:24:38 -05:00
parent 8e511c5dc9
commit b2c1d1cb9f
4 changed files with 83 additions and 62 deletions

View File

@ -172,12 +172,12 @@ func (s *Moonshark) initRunner() error {
// Configure session cookies // Configure session cookies
sessionManager.SetCookieOptions( sessionManager.SetCookieOptions(
"MSSESSID", // name "MoonsharkID", // name
"/", // path "/", // path
"", // domain "", // domain
false, // secure false, // secure
true, // httpOnly true, // httpOnly
86400, // maxAge (1 day) 86400, // maxAge (1 day)
) )
// Set up runner options // Set up runner options

View File

@ -3,6 +3,7 @@ package http
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time" "time"
"Moonshark/core/metadata" "Moonshark/core/metadata"
@ -160,7 +161,7 @@ func HandleMethodNotAllowed(ctx *fasthttp.RequestCtx, errorConfig utils.ErrorPag
// handleLuaRoute executes a Lua route // handleLuaRoute executes a Lua route
func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scriptPath string, params *routers.Params) { 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() defer luaCtx.Release()
method := string(ctx.Method()) method := string(ctx.Method())
@ -242,7 +243,10 @@ func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scrip
return 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 // Content types for responses
@ -258,34 +262,47 @@ func writeResponse(ctx *fasthttp.RequestCtx, result any) {
return return
} }
// Check for HTTPResponse type // First check the raw type of the result for strong type identification
if httpResp, ok := result.(*sandbox.HTTPResponse); ok { // Sometimes type assertions don't work as expected with interface values
defer sandbox.ReleaseResponse(httpResp) resultType := fmt.Sprintf("%T", result)
// Set response headers // Strong check for HTTP response
for name, value := range httpResp.Headers { if strings.Contains(resultType, "HTTPResponse") || strings.Contains(resultType, "sandbox.HTTPResponse") {
ctx.Response.Header.Set(name, value) httpResp, ok := result.(*sandbox.HTTPResponse)
} if ok {
defer sandbox.ReleaseResponse(httpResp)
// Set cookies // Set response headers
for _, cookie := range httpResp.Cookies { for name, value := range httpResp.Headers {
ctx.Response.Header.SetCookie(cookie) ctx.Response.Header.Set(name, value)
} }
// Set status code // Set cookies
ctx.SetStatusCode(httpResp.Status) for _, cookie := range httpResp.Cookies {
ctx.Response.Header.SetCookie(cookie)
}
// Process the body based on its type // Set status code
if httpResp.Body == nil { 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 return
} }
result = httpResp.Body // Set result to body for processing below
} }
// Check if it's a map (table) or array - return as JSON // Check if it's a map (table) or array - return as JSON
isJSON := false isJSON := false
switch result.(type) { switch result.(type) {
case map[string]any, []any, []float64, []string, []int: case map[string]any, []any, []float64, []string, []int:
isJSON = true isJSON = true
@ -303,18 +320,21 @@ func writeResponse(ctx *fasthttp.RequestCtx, result any) {
return return
} }
// All other types - convert to plain text // Handle string and byte slice cases directly
setContentTypeIfMissing(ctx, contentTypePlain)
switch r := result.(type) { switch r := result.(type) {
case string: case string:
setContentTypeIfMissing(ctx, contentTypePlain)
ctx.SetBodyString(r) ctx.SetBodyString(r)
return
case []byte: case []byte:
setContentTypeIfMissing(ctx, contentTypePlain)
ctx.SetBody(r) ctx.SetBody(r)
default: return
// Convert any other type to string
ctx.SetBodyString(fmt.Sprintf("%v", r))
} }
// 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) { func setContentTypeIfMissing(ctx *fasthttp.RequestCtx, contentType string) {

View File

@ -3,7 +3,6 @@ package runner
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sync" "sync"
@ -277,8 +276,21 @@ func (r *Runner) Execute(ctx context.Context, bytecode []byte, execCtx *Context,
ctxValues = execCtx.Values ctxValues = execCtx.Values
} }
// Execute in sandbox // Execute in sandbox with optimized context handling
result, err := state.sandbox.Execute(state.L, bytecode, ctxValues) 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 { if err != nil {
return nil, err return nil, err
} }
@ -290,35 +302,24 @@ func (r *Runner) Execute(ctx context.Context, bytecode []byte, execCtx *Context,
} }
} }
// Check for HTTP response // Check for HTTP response if we don't have a RequestCtx or if we still have a result
httpResp, hasResponse := sandbox.GetHTTPResponse(state.L) if execCtx == nil || execCtx.RequestCtx == nil || result != nil {
if hasResponse { httpResp, hasResponse := sandbox.GetHTTPResponse(state.L)
// Set result as body if not already set if hasResponse {
if httpResp.Body == nil { // Set result as body if not already set
httpResp.Body = result if httpResp.Body == nil {
} httpResp.Body = result
}
// Apply directly to request context if available // Apply directly to request context if available
if execCtx != nil && execCtx.RequestCtx != nil { if execCtx != nil && execCtx.RequestCtx != nil {
sandbox.ApplyHTTPResponse(httpResp, execCtx.RequestCtx) sandbox.ApplyHTTPResponse(httpResp, execCtx.RequestCtx)
sandbox.ReleaseResponse(httpResp) sandbox.ReleaseResponse(httpResp)
return nil, nil return nil, nil
} }
return httpResp, 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 nil, nil
} }
return result, err return result, err

View File

@ -13,7 +13,7 @@ import (
const ( const (
// Default settings // Default settings
DefaultMaxSize = 100 * 1024 * 1024 // 100MB default cache size DefaultMaxSize = 100 * 1024 * 1024 // 100MB default cache size
DefaultCookieName = "MSESSID" DefaultCookieName = "MoonsharkID"
DefaultCookiePath = "/" DefaultCookiePath = "/"
DefaultMaxAge = 86400 // 1 day in seconds DefaultMaxAge = 86400 // 1 day in seconds
) )