refactoring
This commit is contained in:
parent
b13908b93f
commit
efcad468ad
@ -10,12 +10,12 @@ runner = {
|
||||
}
|
||||
|
||||
dirs = {
|
||||
routes = "./routes",
|
||||
static = "./static",
|
||||
fs = "./fs",
|
||||
data = "./data",
|
||||
override = "./override",
|
||||
routes = "routes",
|
||||
static = "public",
|
||||
fs = "fs",
|
||||
data = "data",
|
||||
override = "override",
|
||||
libs = {
|
||||
"./libs"
|
||||
"libs"
|
||||
}
|
||||
}
|
||||
|
@ -107,14 +107,14 @@ func (s *Server) processRequest(ctx *fasthttp.RequestCtx) {
|
||||
logger.Debug("Processing request %s %s", method, path)
|
||||
|
||||
params := &routers.Params{}
|
||||
bytecode, scriptPath, found := s.luaRouter.GetBytecode(method, path, params)
|
||||
bytecode, scriptPath, routeErr, found := s.luaRouter.GetRouteInfo(method, path, params)
|
||||
|
||||
// Check if we found a route but it has no valid bytecode (compile error)
|
||||
if found && len(bytecode) == 0 {
|
||||
// Check if we found a route but it has an error or no valid bytecode
|
||||
if found && (len(bytecode) == 0 || routeErr != nil) {
|
||||
errorMsg := "Route exists but failed to compile. Check server logs for details."
|
||||
|
||||
if node, _ := s.luaRouter.GetNodeWithError(method, path, params); node != nil && node.Error != nil {
|
||||
errorMsg = node.Error.Error()
|
||||
if routeErr != nil {
|
||||
errorMsg = routeErr.Error()
|
||||
}
|
||||
|
||||
logger.Error("%s %s - %s", method, path, errorMsg)
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
func LogRequest(statusCode int, method, path string, duration time.Duration) {
|
||||
var statusColor, resetColor, methodColor string
|
||||
|
||||
// Status code colors
|
||||
if statusCode >= 200 && statusCode < 300 {
|
||||
statusColor = "\u001b[32m" // Green for 2xx
|
||||
} else if statusCode >= 300 && statusCode < 400 {
|
||||
@ -28,7 +27,6 @@ func LogRequest(statusCode int, method, path string, duration time.Duration) {
|
||||
statusColor = "\u001b[31m" // Red for 5xx and others
|
||||
}
|
||||
|
||||
// Method colors
|
||||
switch method {
|
||||
case "GET":
|
||||
methodColor = "\u001b[32m" // Green
|
||||
@ -44,7 +42,6 @@ func LogRequest(statusCode int, method, path string, duration time.Duration) {
|
||||
|
||||
resetColor = "\u001b[0m"
|
||||
|
||||
// Format duration
|
||||
var durationStr string
|
||||
if duration.Milliseconds() < 1 {
|
||||
durationStr = fmt.Sprintf("%.2fµs", float64(duration.Microseconds()))
|
||||
@ -54,7 +51,6 @@ func LogRequest(statusCode int, method, path string, duration time.Duration) {
|
||||
durationStr = fmt.Sprintf("%.2fs", duration.Seconds())
|
||||
}
|
||||
|
||||
// Log with colors
|
||||
logger.Server("%s%d%s %s%s%s %s %s",
|
||||
statusColor, statusCode, resetColor,
|
||||
methodColor, method, resetColor,
|
||||
@ -65,23 +61,17 @@ func LogRequest(statusCode int, method, path string, duration time.Duration) {
|
||||
func QueryToLua(ctx *fasthttp.RequestCtx) map[string]any {
|
||||
queryMap := make(map[string]any)
|
||||
|
||||
// Visit all query parameters
|
||||
ctx.QueryArgs().VisitAll(func(key, value []byte) {
|
||||
// Convert to string
|
||||
k := string(key)
|
||||
v := string(value)
|
||||
|
||||
// Check if this key already exists as an array
|
||||
if existing, ok := queryMap[k]; ok {
|
||||
// If it's already an array, append to it
|
||||
if arr, ok := existing.([]string); ok {
|
||||
queryMap[k] = append(arr, v)
|
||||
} else if str, ok := existing.(string); ok {
|
||||
// Convert existing string to array and append new value
|
||||
queryMap[k] = []string{str, v}
|
||||
}
|
||||
} else {
|
||||
// New key, store as string
|
||||
queryMap[k] = v
|
||||
}
|
||||
})
|
||||
@ -93,27 +83,21 @@ func QueryToLua(ctx *fasthttp.RequestCtx) map[string]any {
|
||||
func ParseForm(ctx *fasthttp.RequestCtx) (map[string]any, error) {
|
||||
formData := make(map[string]any)
|
||||
|
||||
// Check if multipart form
|
||||
if strings.Contains(string(ctx.Request.Header.ContentType()), "multipart/form-data") {
|
||||
return parseMultipartForm(ctx)
|
||||
}
|
||||
|
||||
// Regular form
|
||||
ctx.PostArgs().VisitAll(func(key, value []byte) {
|
||||
k := string(key)
|
||||
v := string(value)
|
||||
|
||||
// Check if this key already exists
|
||||
if existing, ok := formData[k]; ok {
|
||||
// If it's already an array, append to it
|
||||
if arr, ok := existing.([]string); ok {
|
||||
formData[k] = append(arr, v)
|
||||
} else if str, ok := existing.(string); ok {
|
||||
// Convert existing string to array and append new value
|
||||
formData[k] = []string{str, v}
|
||||
}
|
||||
} else {
|
||||
// New key, store as string
|
||||
formData[k] = v
|
||||
}
|
||||
})
|
||||
@ -125,13 +109,11 @@ func ParseForm(ctx *fasthttp.RequestCtx) (map[string]any, error) {
|
||||
func parseMultipartForm(ctx *fasthttp.RequestCtx) (map[string]any, error) {
|
||||
formData := make(map[string]any)
|
||||
|
||||
// Parse multipart form
|
||||
form, err := ctx.MultipartForm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Process form values
|
||||
for key, values := range form.Value {
|
||||
if len(values) == 1 {
|
||||
formData[key] = values[0]
|
||||
@ -140,7 +122,6 @@ func parseMultipartForm(ctx *fasthttp.RequestCtx) (map[string]any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Process files (store file info, not the content)
|
||||
if len(form.File) > 0 {
|
||||
files := make(map[string]any)
|
||||
|
||||
|
@ -214,10 +214,8 @@ func getBytecodeKey(handlerPath string) []byte {
|
||||
// Match finds a handler for the given method and path
|
||||
// Uses the pre-allocated params struct to avoid allocations
|
||||
func (r *LuaRouter) Match(method, path string, params *Params) (*node, bool) {
|
||||
// Reset params
|
||||
params.Count = 0
|
||||
|
||||
// Get route tree for method
|
||||
r.mu.RLock()
|
||||
root, exists := r.routes[method]
|
||||
r.mu.RUnlock()
|
||||
@ -226,10 +224,8 @@ func (r *LuaRouter) Match(method, path string, params *Params) (*node, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Split path
|
||||
segments := strings.Split(strings.Trim(path, "/"), "/")
|
||||
|
||||
// Match path
|
||||
return r.matchPath(root, segments, params, 0)
|
||||
}
|
||||
|
||||
@ -279,122 +275,100 @@ func (r *LuaRouter) compileHandler(n *node) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read the Lua file
|
||||
content, err := os.ReadFile(n.handler)
|
||||
if err != nil {
|
||||
n.err = err // Store the error in the node
|
||||
n.err = err
|
||||
return err
|
||||
}
|
||||
|
||||
// Compile to bytecode
|
||||
state := luajit.New()
|
||||
if state == nil {
|
||||
compileErr := errors.New("failed to create Lua state")
|
||||
n.err = compileErr // Store the error in the node
|
||||
n.err = compileErr
|
||||
return compileErr
|
||||
}
|
||||
defer state.Close()
|
||||
|
||||
bytecode, err := state.CompileBytecode(string(content), n.handler)
|
||||
if err != nil {
|
||||
n.err = err // Store the error in the node
|
||||
n.err = err
|
||||
return err
|
||||
}
|
||||
|
||||
// Store bytecode in cache
|
||||
bytecodeKey := getBytecodeKey(n.handler)
|
||||
r.bytecodeCache.Set(bytecodeKey, bytecode)
|
||||
|
||||
n.err = nil // Clear any previous error
|
||||
n.err = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBytecode returns the compiled bytecode for a matched route
|
||||
// Uses FastCache for both route matching and bytecode retrieval
|
||||
func (r *LuaRouter) GetBytecode(method, path string, params *Params) ([]byte, string, bool) {
|
||||
// Check route cache first
|
||||
// GetRouteInfo returns the bytecode, script path, and any error for a matched route
|
||||
func (r *LuaRouter) GetRouteInfo(method, path string, params *Params) ([]byte, string, error, bool) {
|
||||
routeCacheKey := getCacheKey(method, path)
|
||||
routeCacheData := r.routeCache.Get(nil, routeCacheKey)
|
||||
|
||||
if len(routeCacheData) > 0 {
|
||||
// Cache hit - first 8 bytes are bytecode hash, rest is handler path
|
||||
handlerPath := string(routeCacheData[8:])
|
||||
bytecodeKey := routeCacheData[:8]
|
||||
|
||||
// Get bytecode from cache
|
||||
bytecode := r.bytecodeCache.Get(nil, bytecodeKey)
|
||||
if len(bytecode) > 0 {
|
||||
return bytecode, handlerPath, true
|
||||
}
|
||||
|
||||
// Bytecode not found, check if file was modified
|
||||
n, exists := r.nodeForHandler(handlerPath)
|
||||
if !exists {
|
||||
// Handler no longer exists
|
||||
r.routeCache.Del(routeCacheKey)
|
||||
return nil, "", false
|
||||
return nil, "", nil, false
|
||||
}
|
||||
|
||||
if len(bytecode) > 0 {
|
||||
return bytecode, handlerPath, n.err, true
|
||||
}
|
||||
|
||||
// Check if file was modified
|
||||
fileInfo, err := os.Stat(handlerPath)
|
||||
if err != nil || fileInfo.ModTime().After(n.modTime) {
|
||||
// Recompile if file was modified
|
||||
if err := r.compileHandler(n); err != nil {
|
||||
return nil, handlerPath, true // Return with error
|
||||
return nil, handlerPath, n.err, true
|
||||
}
|
||||
|
||||
// Update cache
|
||||
newBytecodeKey := getBytecodeKey(handlerPath)
|
||||
bytecode = r.bytecodeCache.Get(nil, newBytecodeKey)
|
||||
|
||||
// Update route cache
|
||||
newCacheData := make([]byte, 8+len(handlerPath))
|
||||
copy(newCacheData[:8], newBytecodeKey)
|
||||
copy(newCacheData[8:], handlerPath)
|
||||
r.routeCache.Set(routeCacheKey, newCacheData)
|
||||
|
||||
return bytecode, handlerPath, true
|
||||
return bytecode, handlerPath, n.err, true
|
||||
}
|
||||
|
||||
// Strange case - bytecode not in cache but file not modified
|
||||
// Recompile
|
||||
// Strange case - bytecode not in cache but file not modified; recompile
|
||||
if err := r.compileHandler(n); err != nil {
|
||||
return nil, handlerPath, true
|
||||
return nil, handlerPath, n.err, true
|
||||
}
|
||||
bytecode = r.bytecodeCache.Get(nil, bytecodeKey)
|
||||
return bytecode, handlerPath, true
|
||||
return bytecode, handlerPath, n.err, true
|
||||
}
|
||||
|
||||
// Cache miss - do normal routing
|
||||
node, found := r.Match(method, path, params)
|
||||
if !found {
|
||||
return nil, "", false
|
||||
return nil, "", nil, false
|
||||
}
|
||||
|
||||
// If the route exists but has a compilation error
|
||||
if node.err != nil {
|
||||
return nil, node.handler, true
|
||||
}
|
||||
|
||||
// Get bytecode from cache
|
||||
bytecodeKey := getBytecodeKey(node.handler)
|
||||
bytecode := r.bytecodeCache.Get(nil, bytecodeKey)
|
||||
|
||||
if len(bytecode) == 0 {
|
||||
// Compile if not in cache
|
||||
if err := r.compileHandler(node); err != nil {
|
||||
return nil, node.handler, true
|
||||
return nil, node.handler, node.err, true
|
||||
}
|
||||
bytecode = r.bytecodeCache.Get(nil, bytecodeKey)
|
||||
}
|
||||
|
||||
// Add to route cache
|
||||
cacheData := make([]byte, 8+len(node.handler))
|
||||
copy(cacheData[:8], bytecodeKey)
|
||||
copy(cacheData[8:], node.handler)
|
||||
r.routeCache.Set(routeCacheKey, cacheData)
|
||||
|
||||
return bytecode, node.handler, true
|
||||
return bytecode, node.handler, node.err, true
|
||||
}
|
||||
|
||||
// nodeForHandler finds a node by its handler path
|
||||
@ -428,7 +402,6 @@ func findNodeByHandler(current *node, handlerPath string) *node {
|
||||
}
|
||||
}
|
||||
|
||||
// Check param child
|
||||
if current.paramChild != nil {
|
||||
if node := findNodeByHandler(current.paramChild, handlerPath); node != nil {
|
||||
return node
|
||||
@ -443,20 +416,16 @@ func (r *LuaRouter) Refresh() error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// Reset routes
|
||||
for method := range r.routes {
|
||||
r.routes[method] = &node{
|
||||
staticChild: make(map[string]*node),
|
||||
}
|
||||
}
|
||||
|
||||
// Clear failed routes
|
||||
r.failedRoutes = make(map[string]*RouteError)
|
||||
|
||||
// Rebuild routes
|
||||
err := r.buildRoutes()
|
||||
|
||||
// If some routes failed to compile, return a warning error
|
||||
if len(r.failedRoutes) > 0 {
|
||||
return ErrRoutesCompilationErrors
|
||||
}
|
||||
@ -484,14 +453,14 @@ func (r *LuaRouter) ClearCache() {
|
||||
}
|
||||
|
||||
// GetCacheStats returns statistics about the cache
|
||||
func (r *LuaRouter) GetCacheStats() map[string]interface{} {
|
||||
func (r *LuaRouter) GetCacheStats() map[string]any {
|
||||
var routeStats fastcache.Stats
|
||||
var bytecodeStats fastcache.Stats
|
||||
|
||||
r.routeCache.UpdateStats(&routeStats)
|
||||
r.bytecodeCache.UpdateStats(&bytecodeStats)
|
||||
|
||||
return map[string]interface{}{
|
||||
return map[string]any{
|
||||
"routeEntries": routeStats.EntriesCount,
|
||||
"routeBytes": routeStats.BytesSize,
|
||||
"routeCollisions": routeStats.Collisions,
|
||||
@ -509,7 +478,6 @@ func (r *LuaRouter) GetRouteStats() (int, int64) {
|
||||
routeCount := 0
|
||||
bytecodeBytes := int64(0)
|
||||
|
||||
// Count routes and estimate bytecode size
|
||||
for _, root := range r.routes {
|
||||
count, bytes := countNodesAndBytecode(root)
|
||||
routeCount += count
|
||||
@ -525,21 +493,18 @@ func countNodesAndBytecode(n *node) (count int, bytecodeBytes int64) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// Count this node if it has a handler
|
||||
if n.handler != "" {
|
||||
count = 1
|
||||
// Estimate bytecode size (average of 2KB per script)
|
||||
// Average of 2KB per script
|
||||
bytecodeBytes = 2048
|
||||
}
|
||||
|
||||
// Count static children
|
||||
for _, child := range n.staticChild {
|
||||
childCount, childBytes := countNodesAndBytecode(child)
|
||||
count += childCount
|
||||
bytecodeBytes += childBytes
|
||||
}
|
||||
|
||||
// Count parameter child
|
||||
if n.paramChild != nil {
|
||||
childCount, childBytes := countNodesAndBytecode(n.paramChild)
|
||||
count += childCount
|
||||
@ -553,35 +518,3 @@ type NodeWithError struct {
|
||||
ScriptPath string
|
||||
Error error
|
||||
}
|
||||
|
||||
// GetNodeWithError returns the node with its error for a given path
|
||||
func (r *LuaRouter) GetNodeWithError(method, path string, params *Params) (*NodeWithError, bool) {
|
||||
// Try route cache first
|
||||
routeCacheKey := getCacheKey(method, path)
|
||||
routeCacheData := r.routeCache.Get(nil, routeCacheKey)
|
||||
|
||||
if len(routeCacheData) > 0 {
|
||||
// Cache hit - get handler path
|
||||
handlerPath := string(routeCacheData[8:])
|
||||
|
||||
// Find the node for this handler
|
||||
node, found := r.nodeForHandler(handlerPath)
|
||||
if found {
|
||||
return &NodeWithError{
|
||||
ScriptPath: node.handler,
|
||||
Error: node.err,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
// Cache miss - do normal routing
|
||||
node, found := r.Match(method, path, params)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &NodeWithError{
|
||||
ScriptPath: node.handler,
|
||||
Error: node.err,
|
||||
}, true
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ type StaticRouter struct {
|
||||
|
||||
// NewStaticRouter creates a new StaticRouter instance
|
||||
func NewStaticRouter(rootDir string) (*StaticRouter, error) {
|
||||
// Verify root directory exists
|
||||
info, err := os.Stat(rootDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -49,7 +48,7 @@ func NewStaticRouter(rootDir string) (*StaticRouter, error) {
|
||||
|
||||
r := &StaticRouter{
|
||||
fs: fs,
|
||||
urlPrefix: "/",
|
||||
urlPrefix: "",
|
||||
rootDir: rootDir,
|
||||
log: false,
|
||||
useBrotli: true,
|
||||
|
@ -56,12 +56,12 @@ func New() *Config {
|
||||
config.Runner.PoolSize = runtime.GOMAXPROCS(0)
|
||||
|
||||
// Dirs defaults
|
||||
config.Dirs.Routes = "./routes"
|
||||
config.Dirs.Static = "./static"
|
||||
config.Dirs.FS = "./fs"
|
||||
config.Dirs.Data = "./data"
|
||||
config.Dirs.Override = "./override"
|
||||
config.Dirs.Libs = []string{"./libs"}
|
||||
config.Dirs.Routes = "routes"
|
||||
config.Dirs.Static = "public"
|
||||
config.Dirs.FS = "fs"
|
||||
config.Dirs.Data = "data"
|
||||
config.Dirs.Override = "override"
|
||||
config.Dirs.Libs = []string{"libs"}
|
||||
|
||||
return config
|
||||
}
|
||||
|
12
go.mod
12
go.mod
@ -3,22 +3,22 @@ module Moonshark
|
||||
go 1.24.1
|
||||
|
||||
require (
|
||||
git.sharkk.net/Sky/LuaJIT-to-Go v0.0.0
|
||||
git.sharkk.net/Sky/LuaJIT-to-Go v0.1.2
|
||||
github.com/VictoriaMetrics/fastcache v1.12.2
|
||||
github.com/deneonet/benc v1.1.7
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/matoous/go-nanoid/v2 v2.1.0
|
||||
github.com/valyala/bytebufferpool v1.0.0
|
||||
github.com/valyala/fasthttp v1.60.0
|
||||
github.com/valyala/fasthttp v1.61.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
)
|
||||
|
||||
replace git.sharkk.net/Sky/LuaJIT-to-Go => ./luajit
|
||||
|
18
go.sum
18
go.sum
@ -4,8 +4,9 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah
|
||||
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/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
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.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -13,8 +14,9 @@ github.com/deneonet/benc v1.1.7 h1:0XPxTTVJZq/ulxXvMn2Mzjx5XquekVky3wX6eTgA0vA=
|
||||
github.com/deneonet/benc v1.1.7/go.mod h1:UCfkM5Od0B2huwv/ZItvtUb7QnALFt9YXtX8NXX4Lts=
|
||||
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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE=
|
||||
@ -27,14 +29,14 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
||||
github.com/stretchr/testify v1.9.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/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
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.61.0 h1:VV08V0AfoRaFurP1EWKvQQdPTZHiUzaVoulX1aBDgzU=
|
||||
github.com/valyala/fasthttp v1.61.0/go.mod h1:wRIV/4cMwUPWnRcDno9hGnYZGh78QzODFfo1LTUhBog=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
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/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.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=
|
||||
|
2
luajit
2
luajit
@ -1 +1 @@
|
||||
Subproject commit a2b4b1c9272f849d9c1c913366f822e0be904ba2
|
||||
Subproject commit 6b9e2a0e201bdd34fba0972441434354aa5c67c5
|
Loading…
x
Reference in New Issue
Block a user