add http utils
This commit is contained in:
parent
780533bd76
commit
0259d1a135
|
@ -170,27 +170,33 @@ func writeResponse(w http.ResponseWriter, result any, log *logger.Logger) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch res := result.(type) {
|
// Check for HTTPResponse type
|
||||||
case string:
|
if httpResp, ok := result.(*runner.HTTPResponse); ok {
|
||||||
// String result
|
// Set response headers
|
||||||
w.Header().Set("Content-Type", contentTypePlain)
|
for name, value := range httpResp.Headers {
|
||||||
w.Write([]byte(res))
|
w.Header().Set(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
case map[string]any, []any:
|
// Set status code
|
||||||
// Table or array result - convert to JSON
|
w.WriteHeader(httpResp.Status)
|
||||||
w.Header().Set("Content-Type", contentTypeJSON)
|
|
||||||
data, err := json.Marshal(res)
|
// Process the body based on its type
|
||||||
if err != nil {
|
if httpResp.Body == nil {
|
||||||
log.Error("Failed to marshal response: %v", err)
|
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Write(data)
|
|
||||||
|
|
||||||
|
result = httpResp.Body // Set result to body for processing below
|
||||||
|
}
|
||||||
|
|
||||||
|
switch res := result.(type) {
|
||||||
|
case string:
|
||||||
|
// String result - plain text
|
||||||
|
setContentTypeIfMissing(w, contentTypePlain)
|
||||||
|
w.Write([]byte(res))
|
||||||
default:
|
default:
|
||||||
// Other result types - convert to JSON
|
// All other types - convert to JSON
|
||||||
w.Header().Set("Content-Type", contentTypeJSON)
|
setContentTypeIfMissing(w, contentTypeJSON)
|
||||||
data, err := json.Marshal(result)
|
data, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to marshal response: %v", err)
|
log.Error("Failed to marshal response: %v", err)
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
@ -199,3 +205,9 @@ func writeResponse(w http.ResponseWriter, result any, log *logger.Logger) {
|
||||||
w.Write(data)
|
w.Write(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setContentTypeIfMissing(w http.ResponseWriter, contentType string) {
|
||||||
|
if w.Header().Get("Content-Type") == "" {
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -103,18 +103,25 @@ func NewRunner(options ...RunnerOption) (*LuaRunner, error) {
|
||||||
return nil, ErrInitFailed
|
return nil, ErrInitFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize HTTP module BEFORE sandbox setup
|
||||||
|
httpInit := HTTPModuleInitFunc()
|
||||||
|
if err := httpInit(state); err != nil {
|
||||||
|
state.Close()
|
||||||
|
return nil, ErrInitFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up sandbox AFTER HTTP module is initialized
|
||||||
|
if err := runner.sandbox.Setup(state); err != nil {
|
||||||
|
state.Close()
|
||||||
|
return nil, ErrInitFailed
|
||||||
|
}
|
||||||
|
|
||||||
// Preload all modules into package.loaded
|
// Preload all modules into package.loaded
|
||||||
if err := runner.moduleLoader.PreloadAllModules(state); err != nil {
|
if err := runner.moduleLoader.PreloadAllModules(state); err != nil {
|
||||||
state.Close()
|
state.Close()
|
||||||
return nil, errors.New("failed to preload modules")
|
return nil, errors.New("failed to preload modules")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up sandbox
|
|
||||||
if err := runner.sandbox.Setup(state); err != nil {
|
|
||||||
state.Close()
|
|
||||||
return nil, ErrInitFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run init function if provided
|
// Run init function if provided
|
||||||
if runner.initFunc != nil {
|
if runner.initFunc != nil {
|
||||||
if err := runner.initFunc(state); err != nil {
|
if err := runner.initFunc(state); err != nil {
|
||||||
|
|
|
@ -12,10 +12,12 @@ type Sandbox struct {
|
||||||
|
|
||||||
// NewSandbox creates a new sandbox
|
// NewSandbox creates a new sandbox
|
||||||
func NewSandbox() *Sandbox {
|
func NewSandbox() *Sandbox {
|
||||||
return &Sandbox{
|
s := &Sandbox{
|
||||||
modules: make(map[string]any),
|
modules: make(map[string]any),
|
||||||
initialized: false,
|
initialized: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddModule adds a module to the sandbox environment
|
// AddModule adds a module to the sandbox environment
|
||||||
|
@ -78,6 +80,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
preload = package.preload
|
preload = package.preload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Add HTTP module explicitly to the base environment
|
||||||
|
base.http = http
|
||||||
|
|
||||||
-- Add registered custom modules
|
-- Add registered custom modules
|
||||||
if __sandbox_modules then
|
if __sandbox_modules then
|
||||||
for name, mod in pairs(__sandbox_modules) do
|
for name, mod in pairs(__sandbox_modules) do
|
||||||
|
@ -90,6 +95,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
__env_system.initialized = true
|
__env_system.initialized = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Global variable for tracking current environment
|
||||||
|
__last_env = nil
|
||||||
|
|
||||||
-- Fast environment creation with pre-allocation
|
-- Fast environment creation with pre-allocation
|
||||||
function __get_sandbox_env(ctx)
|
function __get_sandbox_env(ctx)
|
||||||
local env
|
local env
|
||||||
|
@ -101,6 +109,8 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
|
|
||||||
-- Clear any previous context
|
-- Clear any previous context
|
||||||
env.ctx = ctx or nil
|
env.ctx = ctx or nil
|
||||||
|
-- Clear any previous response
|
||||||
|
env._response = nil
|
||||||
else
|
else
|
||||||
-- Create new environment with metatable inheritance
|
-- Create new environment with metatable inheritance
|
||||||
env = setmetatable({}, {
|
env = setmetatable({}, {
|
||||||
|
@ -118,6 +128,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Store reference to current environment
|
||||||
|
__last_env = env
|
||||||
|
|
||||||
return env
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,6 +140,7 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
||||||
if __env_system.pool_size < __env_system.max_pool_size then
|
if __env_system.pool_size < __env_system.max_pool_size then
|
||||||
-- Clear context reference to avoid memory leaks
|
-- Clear context reference to avoid memory leaks
|
||||||
env.ctx = nil
|
env.ctx = nil
|
||||||
|
-- Don't clear response data - we need it for extraction
|
||||||
|
|
||||||
-- Add to pool
|
-- Add to pool
|
||||||
table.insert(__env_system.env_pool, env)
|
table.insert(__env_system.env_pool, env)
|
||||||
|
@ -239,7 +253,14 @@ func (s *Sandbox) Execute(state *luajit.State, bytecode []byte, ctx map[string]a
|
||||||
|
|
||||||
// Get result
|
// Get result
|
||||||
result, err := state.ToValue(-1)
|
result, err := state.ToValue(-1)
|
||||||
state.Pop(1)
|
state.Pop(1) // Pop result
|
||||||
|
|
||||||
|
// Check if HTTP response was set
|
||||||
|
httpResponse, hasHTTPResponse := GetHTTPResponse(state)
|
||||||
|
if hasHTTPResponse {
|
||||||
|
httpResponse.Body = result
|
||||||
|
return httpResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user