cleanup 1

This commit is contained in:
Sky Johnson 2025-04-04 10:49:16 -05:00
parent 23239b00fc
commit 0a18167df7
7 changed files with 103 additions and 508 deletions

5
.gitignore vendored
View File

@ -24,7 +24,4 @@ go.work
# Test directories and files # Test directories and files
config.lua config.lua
routes/ test/
static/
libs/
override/

View File

@ -172,12 +172,12 @@ func (s *Moonshark) initRunner() error {
// Configure session cookies // Configure session cookies
sessionManager.SetCookieOptions( sessionManager.SetCookieOptions(
"MSESSID", // name "MSSESSID", // 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

@ -29,7 +29,6 @@ type Config struct {
HTTPLoggingEnabled bool HTTPLoggingEnabled bool
Watchers struct { Watchers struct {
Routes bool Routes bool
Static bool
Modules bool Modules bool
} }
@ -64,121 +63,106 @@ func New() *Config {
// Load loads configuration from a Lua file // Load loads configuration from a Lua file
func Load(filePath string) (*Config, error) { func Load(filePath string) (*Config, error) {
// For simple configs, use standard libraries to ensure proper loading // Create Lua state
state := luajit.New(true) state := luajit.New(true)
if state == nil { if state == nil {
return nil, errors.New("failed to create Lua state") return nil, errors.New("failed to create Lua state")
} }
defer state.Close() defer state.Close()
defer state.Cleanup()
// Create config with default values // Create config with default values
config := New() config := New()
// Execute the config file // Execute the config file
if err := state.DoFile(filePath); err != nil { if err := state.DoFile(filePath); err != nil {
return nil, fmt.Errorf("%w", err) return nil, fmt.Errorf("failed to load config file: %w", err)
} }
// Extract configuration values // Store values directly to the config
extractConfig(state, config) config.values = make(map[string]any)
// Extract all globals individually
globalKeys := []string{
"debug", "log_level", "port", "routes_dir", "static_dir",
"override_dir", "pool_size", "http_logging_enabled",
"watchers", "lib_dirs",
}
for _, key := range globalKeys {
state.GetGlobal(key)
if !state.IsNil(-1) {
value, err := state.ToValue(-1)
if err == nil {
config.values[key] = value
}
}
state.Pop(1)
}
// Apply configuration values
applyConfig(config, config.values)
return config, nil return config, nil
} }
// extractConfig extracts configuration values directly by name // applyConfig applies configuration values from the globals map
func extractConfig(state *luajit.State, config *Config) { func applyConfig(config *Config, globals map[string]any) {
// Process known config values directly by key // Server settings
if value := extractValue(state, "debug"); value != nil { if v, ok := globals["debug"].(bool); ok {
if boolVal, ok := value.(bool); ok { config.Debug = v
config.Debug = boolVal }
} if v, ok := globals["log_level"].(string); ok {
config.LogLevel = v
}
if v, ok := globals["port"].(float64); ok {
config.Port = int(v)
} }
if value := extractValue(state, "log_level"); value != nil { // Directory paths
if strVal, ok := value.(string); ok { if v, ok := globals["routes_dir"].(string); ok {
config.LogLevel = strVal config.RoutesDir = v
} }
if v, ok := globals["static_dir"].(string); ok {
config.StaticDir = v
}
if v, ok := globals["override_dir"].(string); ok {
config.OverrideDir = v
} }
if value := extractValue(state, "port"); value != nil { // Performance settings
if numVal, ok := value.(float64); ok { if v, ok := globals["pool_size"].(float64); ok {
config.Port = int(numVal) config.PoolSize = int(v)
}
} }
if value := extractValue(state, "routes_dir"); value != nil { // Feature flags
if strVal, ok := value.(string); ok { if v, ok := globals["http_logging_enabled"].(bool); ok {
config.RoutesDir = strVal config.HTTPLoggingEnabled = v
}
} }
if value := extractValue(state, "static_dir"); value != nil { // Handle lib_dirs array more efficiently
if strVal, ok := value.(string); ok { if libDirs, ok := globals["lib_dirs"]; ok {
config.StaticDir = strVal if dirs := extractStringArray(libDirs); len(dirs) > 0 {
} config.LibDirs = dirs
}
if value := extractValue(state, "override_dir"); value != nil {
if strVal, ok := value.(string); ok {
config.OverrideDir = strVal
}
}
if value := extractValue(state, "pool_size"); value != nil {
if numVal, ok := value.(float64); ok {
config.PoolSize = int(numVal)
}
}
if value := extractValue(state, "http_logging_enabled"); value != nil {
if boolVal, ok := value.(bool); ok {
config.HTTPLoggingEnabled = boolVal
} }
} }
// Handle watchers table // Handle watchers table
if value := extractValue(state, "watchers"); value != nil { if watchersVal, ok := globals["watchers"]; ok {
if table, ok := value.(map[string]any); ok { if watchers, ok := watchersVal.(map[string]any); ok {
if routes, ok := table["routes"].(bool); ok { if v, ok := watchers["routes"].(bool); ok {
config.Watchers.Routes = routes config.Watchers.Routes = v
} }
if static, ok := table["static"].(bool); ok { if v, ok := watchers["modules"].(bool); ok {
config.Watchers.Static = static config.Watchers.Modules = v
} }
if modules, ok := table["modules"].(bool); ok {
config.Watchers.Modules = modules
}
}
}
// Handle lib_dirs array
if value := extractValue(state, "lib_dirs"); value != nil {
if dirs := extractStringArray(value); len(dirs) > 0 {
config.LibDirs = dirs
} }
} }
} }
// extractValue extracts a specific global value from the Lua state // extractStringArray extracts a string array from a Lua table
func extractValue(state *luajit.State, key string) any {
state.GetGlobal(key)
defer state.Pop(1)
if state.IsNil(-1) {
return nil
}
value, err := state.ToValue(-1)
if err != nil {
return nil
}
return value
}
// extractStringArray extracts a string array from various possible formats
func extractStringArray(value any) []string { func extractStringArray(value any) []string {
// Check if it's a direct array // Direct array case
if arr, ok := value.([]any); ok { if arr, ok := value.([]any); ok {
result := make([]string, 0, len(arr)) result := make([]string, 0, len(arr))
for _, v := range arr { for _, v := range arr {
@ -189,35 +173,15 @@ func extractStringArray(value any) []string {
return result return result
} }
// Check if it's in special array format (map with empty key) // Map with numeric keys case
valueMap, ok := value.(map[string]any) if tableMap, ok := value.(map[string]any); ok {
if !ok { result := make([]string, 0, len(tableMap))
return nil for _, v := range tableMap {
}
arr, ok := valueMap[""]
if !ok {
return nil
}
// Handle different array types
switch arr := arr.(type) {
case []string:
return arr
case []any:
result := make([]string, 0, len(arr))
for _, v := range arr {
if str, ok := v.(string); ok { if str, ok := v.(string); ok {
result = append(result, str) result = append(result, str)
} }
} }
return result return result
case []float64:
result := make([]string, 0, len(arr))
for _, v := range arr {
result = append(result, fmt.Sprintf("%g", v))
}
return result
} }
return nil return nil

View File

@ -486,3 +486,15 @@ func (l *ModuleLoader) ResetModules(state *luajit.State) error {
end end
`) `)
} }
// escapeLuaString escapes special characters in a string for Lua
func escapeLuaString(s string) string {
replacer := strings.NewReplacer(
"\\", "\\\\",
"\"", "\\\"",
"\n", "\\n",
"\r", "\\r",
"\t", "\\t",
)
return replacer.Replace(s)
}

View File

@ -1,388 +0,0 @@
package runner
import (
"os"
"path/filepath"
"strings"
"sync"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
)
// RequireConfig holds configuration for Lua's require mechanism
type RequireConfig struct {
ScriptDir string // Base directory for script being executed
LibDirs []string // Additional library directories
}
// NativeModuleLoader uses Lua's native package.loaded as the cache
type NativeModuleLoader struct {
registry *ModuleRegistry
config *RequireConfig
mu sync.RWMutex
}
// NewNativeModuleLoader creates a new native module loader
func NewNativeModuleLoader(config *RequireConfig) *NativeModuleLoader {
return &NativeModuleLoader{
registry: NewModuleRegistry(),
config: config,
}
}
// escapeLuaString escapes special characters in a string for Lua
func escapeLuaString(s string) string {
replacer := strings.NewReplacer(
"\\", "\\\\",
"\"", "\\\"",
"\n", "\\n",
"\r", "\\r",
"\t", "\\t",
)
return replacer.Replace(s)
}
// SetupRequire configures the require system
func (l *NativeModuleLoader) SetupRequire(state *luajit.State) error {
// Initialize our module registry in Lua
return state.DoString(`
-- Initialize global module registry
__module_paths = {}
-- Setup fast module loading system
__module_results = {}
-- Create module preload table
package.preload = package.preload or {}
-- Setup module loader registry
__ready_modules = {}
`)
}
// PreloadAllModules fully preloads modules for maximum performance
func (l *NativeModuleLoader) PreloadAllModules(state *luajit.State) error {
l.mu.Lock()
defer l.mu.Unlock()
// Reset registry
l.registry = NewModuleRegistry()
// Reset preloaded modules in Lua
if err := state.DoString(`
-- Reset module registry
__module_paths = {}
__module_results = {}
-- Clear non-core modules from package.loaded
local core_modules = {
string = true, table = true, math = true, os = true,
package = true, io = true, coroutine = true, debug = true, _G = true
}
for name in pairs(package.loaded) do
if not core_modules[name] then
package.loaded[name] = nil
end
end
-- Reset preload table
package.preload = package.preload or {}
for name in pairs(package.preload) do
package.preload[name] = nil
end
-- Reset ready modules
__ready_modules = {}
`); err != nil {
return err
}
// Set up paths for require
absPaths := []string{}
pathsMap := map[string]bool{}
// Add script directory (absolute path)
if l.config.ScriptDir != "" {
absPath, err := filepath.Abs(l.config.ScriptDir)
if err == nil && !pathsMap[absPath] {
absPaths = append(absPaths, filepath.Join(absPath, "?.lua"))
pathsMap[absPath] = true
}
}
// Add lib directories (absolute paths)
for _, dir := range l.config.LibDirs {
if dir == "" {
continue
}
absPath, err := filepath.Abs(dir)
if err == nil && !pathsMap[absPath] {
absPaths = append(absPaths, filepath.Join(absPath, "?.lua"))
pathsMap[absPath] = true
}
}
// Set package.path
escapedPathStr := escapeLuaString(strings.Join(absPaths, ";"))
if err := state.DoString(`package.path = "` + escapedPathStr + `"`); err != nil {
return err
}
// Process and preload all modules from lib directories
for _, dir := range l.config.LibDirs {
if dir == "" {
continue
}
absDir, err := filepath.Abs(dir)
if err != nil {
continue
}
// Find all Lua files
err = filepath.Walk(absDir, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() || !strings.HasSuffix(path, ".lua") {
return nil
}
// Get module name
relPath, err := filepath.Rel(absDir, path)
if err != nil || strings.HasPrefix(relPath, "..") {
return nil
}
modName := strings.TrimSuffix(relPath, ".lua")
modName = strings.ReplaceAll(modName, string(filepath.Separator), ".")
// Register module path
l.registry.Register(path, modName)
// Register path in Lua
escapedPath := escapeLuaString(path)
escapedName := escapeLuaString(modName)
if err := state.DoString(`__module_paths["` + escapedName + `"] = "` + escapedPath + `"`); err != nil {
return nil
}
// Compile the module
content, err := os.ReadFile(path)
if err != nil {
return nil
}
// Precompile bytecode
bytecode, err := state.CompileBytecode(string(content), path)
if err != nil {
return nil
}
// Load bytecode
if err := state.LoadBytecode(bytecode, path); err != nil {
return nil
}
// Store in package.preload for fast loading
// We use string concat for efficiency (no string.format overhead)
luaCode := `
local modname = "` + escapedName + `"
local chunk = ...
package.preload[modname] = chunk
__ready_modules[modname] = true
`
if err := state.DoString(luaCode); err != nil {
state.Pop(1) // Remove chunk from stack
return nil
}
state.Pop(1) // Remove chunk from stack
return nil
})
if err != nil {
return err
}
}
// Install optimized require implementation
return state.DoString(`
-- Ultra-fast module loader
function __fast_require(env, modname)
-- 1. Check already loaded modules
if package.loaded[modname] then
return package.loaded[modname]
end
-- 2. Check preloaded chunks
if __ready_modules[modname] then
local loader = package.preload[modname]
if loader then
-- Set environment
setfenv(loader, env)
-- Execute and store result
local result = loader()
if result == nil then
result = true
end
-- Cache in shared registry
package.loaded[modname] = result
return result
end
end
-- 3. Direct file load as fallback
if __module_paths[modname] then
local path = __module_paths[modname]
local chunk, err = loadfile(path)
if chunk then
setfenv(chunk, env)
local result = chunk()
if result == nil then
result = true
end
package.loaded[modname] = result
return result
end
end
-- 4. Full path search as last resort
local err_msgs = {}
for path in package.path:gmatch("[^;]+") do
local file_path = path:gsub("?", modname:gsub("%.", "/"))
local chunk, err = loadfile(file_path)
if chunk then
setfenv(chunk, env)
local result = chunk()
if result == nil then
result = true
end
package.loaded[modname] = result
return result
end
table.insert(err_msgs, "no file '" .. file_path .. "'")
end
error("module '" .. modname .. "' not found:\n" .. table.concat(err_msgs, "\n"), 2)
end
-- Install require factory
function __setup_require(env)
-- Create highly optimized require with closure
env.require = function(modname)
return __fast_require(env, modname)
end
return env
end
`)
}
// NotifyFileChanged invalidates modules when files change
func (l *NativeModuleLoader) NotifyFileChanged(state *luajit.State, path string) bool {
path = filepath.Clean(path)
// Get module name from registry
modName, found := l.registry.GetModuleName(path)
if !found {
// Try to find by path for lib dirs
for _, libDir := range l.config.LibDirs {
absDir, err := filepath.Abs(libDir)
if err != nil {
continue
}
relPath, err := filepath.Rel(absDir, path)
if err != nil || strings.HasPrefix(relPath, "..") {
continue
}
if strings.HasSuffix(relPath, ".lua") {
modName = strings.TrimSuffix(relPath, ".lua")
modName = strings.ReplaceAll(modName, string(filepath.Separator), ".")
found = true
break
}
}
}
if !found {
return false
}
// Check if this is a core module
coreName, isCoreModule := GlobalRegistry.MatchModuleName(modName)
// Invalidate module in Lua
escapedName := escapeLuaString(modName)
invalidateCode := `
package.loaded["` + escapedName + `"] = nil
__ready_modules["` + escapedName + `"] = nil
if package.preload then
package.preload["` + escapedName + `"] = nil
end
`
if err := state.DoString(invalidateCode); err != nil {
return false
}
// For core modules, reinitialize them
if isCoreModule {
if err := GlobalRegistry.InitializeModule(state, coreName); err != nil {
return false
}
return true
}
// For regular modules, update bytecode if the file still exists
content, err := os.ReadFile(path)
if err != nil {
// File might have been deleted - just invalidate
return true
}
// Recompile module
bytecode, err := state.CompileBytecode(string(content), path)
if err != nil {
// Invalid Lua - just invalidate
return true
}
// Load bytecode
if err := state.LoadBytecode(bytecode, path); err != nil {
// Unable to load - just invalidate
return true
}
// Update preload with new chunk for regular modules
luaCode := `
-- Update module in package.preload and clear loaded
package.loaded["` + escapedName + `"] = nil
package.preload["` + escapedName + `"] = ...
__ready_modules["` + escapedName + `"] = true
`
if err := state.DoString(luaCode); err != nil {
state.Pop(1) // Remove chunk from stack
return false
}
state.Pop(1) // Remove chunk from stack
return true
}
// ResetModules clears all non-core modules
func (l *NativeModuleLoader) ResetModules(state *luajit.State) error {
return state.DoString(`
local core_modules = {
string = true, table = true, math = true, os = true,
package = true, io = true, coroutine = true, debug = true, _G = true
}
for name in pairs(package.loaded) do
if not core_modules[name] then
package.loaded[name] = nil
end
end
`)
}

14
go.mod
View File

@ -2,18 +2,20 @@ module git.sharkk.net/Sky/Moonshark
go 1.24.1 go 1.24.1
require git.sharkk.net/Sky/LuaJIT-to-Go v0.0.0 require (
git.sharkk.net/Sky/LuaJIT-to-Go v0.0.0
github.com/VictoriaMetrics/fastcache v1.12.2
github.com/goccy/go-json v0.10.5
github.com/panjf2000/ants/v2 v2.11.2
github.com/valyala/bytebufferpool v1.0.0
github.com/valyala/fasthttp v1.60.0
)
require ( require (
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect github.com/andybalholm/brotli v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/compress v1.18.0 // indirect
github.com/panjf2000/ants/v2 v2.11.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.60.0 // indirect
golang.org/x/sync v0.12.0 // indirect golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect golang.org/x/sys v0.31.0 // indirect
) )

8
go.sum
View File

@ -1,11 +1,13 @@
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=
github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
@ -15,16 +17,22 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/panjf2000/ants/v2 v2.11.2 h1:AVGpMSePxUNpcLaBO34xuIgM1ZdKOiGnpxLXixLi5Jo= github.com/panjf2000/ants/v2 v2.11.2 h1:AVGpMSePxUNpcLaBO34xuIgM1ZdKOiGnpxLXixLi5Jo=
github.com/panjf2000/ants/v2 v2.11.2/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek= github.com/panjf2000/ants/v2 v2.11.2/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.60.0 h1:kBRYS0lOhVJ6V+bYN8PqAHELKHtXqwq9zNMLKx1MBsw= github.com/valyala/fasthttp v1.60.0 h1:kBRYS0lOhVJ6V+bYN8PqAHELKHtXqwq9zNMLKx1MBsw=
github.com/valyala/fasthttp v1.60.0/go.mod h1:iY4kDgV3Gc6EqhRZ8icqcmlG6bqhcDXfuHgTO4FXCvc= github.com/valyala/fasthttp v1.60.0/go.mod h1:iY4kDgV3Gc6EqhRZ8icqcmlG6bqhcDXfuHgTO4FXCvc=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=