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
|
||||
}
|
||||
|
||||
switch res := result.(type) {
|
||||
case string:
|
||||
// String result
|
||||
w.Header().Set("Content-Type", contentTypePlain)
|
||||
w.Write([]byte(res))
|
||||
// Check for HTTPResponse type
|
||||
if httpResp, ok := result.(*runner.HTTPResponse); ok {
|
||||
// Set response headers
|
||||
for name, value := range httpResp.Headers {
|
||||
w.Header().Set(name, value)
|
||||
}
|
||||
|
||||
case map[string]any, []any:
|
||||
// Table or array result - convert to JSON
|
||||
w.Header().Set("Content-Type", contentTypeJSON)
|
||||
data, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
log.Error("Failed to marshal response: %v", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
// Set status code
|
||||
w.WriteHeader(httpResp.Status)
|
||||
|
||||
// Process the body based on its type
|
||||
if httpResp.Body == nil {
|
||||
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:
|
||||
// Other result types - convert to JSON
|
||||
w.Header().Set("Content-Type", contentTypeJSON)
|
||||
data, err := json.Marshal(result)
|
||||
// All other types - convert to JSON
|
||||
setContentTypeIfMissing(w, contentTypeJSON)
|
||||
data, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
log.Error("Failed to marshal response: %v", err)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
if err := runner.moduleLoader.PreloadAllModules(state); err != nil {
|
||||
state.Close()
|
||||
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
|
||||
if runner.initFunc != nil {
|
||||
if err := runner.initFunc(state); err != nil {
|
||||
|
|
|
@ -12,10 +12,12 @@ type Sandbox struct {
|
|||
|
||||
// NewSandbox creates a new sandbox
|
||||
func NewSandbox() *Sandbox {
|
||||
return &Sandbox{
|
||||
s := &Sandbox{
|
||||
modules: make(map[string]any),
|
||||
initialized: false,
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// AddModule adds a module to the sandbox environment
|
||||
|
@ -78,6 +80,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
|||
preload = package.preload
|
||||
}
|
||||
|
||||
-- Add HTTP module explicitly to the base environment
|
||||
base.http = http
|
||||
|
||||
-- Add registered custom modules
|
||||
if __sandbox_modules then
|
||||
for name, mod in pairs(__sandbox_modules) do
|
||||
|
@ -90,6 +95,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
|||
__env_system.initialized = true
|
||||
end
|
||||
|
||||
-- Global variable for tracking current environment
|
||||
__last_env = nil
|
||||
|
||||
-- Fast environment creation with pre-allocation
|
||||
function __get_sandbox_env(ctx)
|
||||
local env
|
||||
|
@ -101,6 +109,8 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
|||
|
||||
-- Clear any previous context
|
||||
env.ctx = ctx or nil
|
||||
-- Clear any previous response
|
||||
env._response = nil
|
||||
else
|
||||
-- Create new environment with metatable inheritance
|
||||
env = setmetatable({}, {
|
||||
|
@ -118,6 +128,9 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
|||
end
|
||||
end
|
||||
|
||||
-- Store reference to current environment
|
||||
__last_env = env
|
||||
|
||||
return env
|
||||
end
|
||||
|
||||
|
@ -127,6 +140,7 @@ func (s *Sandbox) Setup(state *luajit.State) error {
|
|||
if __env_system.pool_size < __env_system.max_pool_size then
|
||||
-- Clear context reference to avoid memory leaks
|
||||
env.ctx = nil
|
||||
-- Don't clear response data - we need it for extraction
|
||||
|
||||
-- Add to pool
|
||||
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
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user