From 818aa23739786ad5de2768fdefbc3fb6381ca2f6 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 11 Jun 2026 16:22:55 +0800 Subject: [PATCH] fix(logging,mimeutil,variable): correct data corruption and behavior bugs - logging: pre-allocate fresh slice for request field to avoid mutating fasthttp internal buffers via append into slices with excess capacity - mimeutil: move defaultMIME fallback before cache insertion so unknown extensions are consistently cached as application/octet-stream - builtin: use -0700 timezone format instead of hardcoded +0800; cache generated request_id in UserValue to prevent different IDs per expansion - variable: initialize maps in fallback Context to prevent nil map panic --- internal/logging/logging.go | 8 +++++++- internal/mimeutil/detect.go | 11 ++++++----- internal/variable/builtin.go | 8 +++++--- internal/variable/variable.go | 7 ++++++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/internal/logging/logging.go b/internal/logging/logging.go index 652b3ca..58c691f 100644 --- a/internal/logging/logging.go +++ b/internal/logging/logging.go @@ -142,9 +142,15 @@ func getOutput(path string) io.Writer { func (l *Logger) LogAccess(ctx *fasthttp.RequestCtx, status int, size int64, duration time.Duration) { // JSON 格式或空格式:输出结构化 JSON if l.accessFormat == formatJSON || l.accessFormat == "" { + method := ctx.Method() + path := ctx.Path() + req := make([]byte, 0, len(method)+1+len(path)) + req = append(req, method...) + req = append(req, ' ') + req = append(req, path...) l.accessLog.Info(). Str("remote_addr", netutil.FormatRemoteAddr(ctx)). - Bytes("request", append(append(ctx.Method(), ' '), ctx.Path()...)). + Bytes("request", req). Int("status", status). Int64("body_bytes_sent", size). Dur("request_time", duration). diff --git a/internal/mimeutil/detect.go b/internal/mimeutil/detect.go index c1c9071..23e4b9f 100644 --- a/internal/mimeutil/detect.go +++ b/internal/mimeutil/detect.go @@ -146,16 +146,17 @@ func DetectContentType(filePath string) string { } } - // 插入新条目 - entry := &mimeCacheEntry{ext: ext, mimeType: mimeType} - entry.element = mimeLRU.PushFront(entry) - mimeCache[ext] = entry - + // 未知扩展名回退到默认值 if mimeType == "" { defaultMutex.RLock() mimeType = defaultMIME defaultMutex.RUnlock() } + // 插入新条目 + entry := &mimeCacheEntry{ext: ext, mimeType: mimeType} + entry.element = mimeLRU.PushFront(entry) + mimeCache[ext] = entry + return mimeType } diff --git a/internal/variable/builtin.go b/internal/variable/builtin.go index 0cfc6e2..0431869 100644 --- a/internal/variable/builtin.go +++ b/internal/variable/builtin.go @@ -255,7 +255,7 @@ func init() { Name: VarTimeLocal, Description: "本地时间(格式:02/Jan/2024:15:04:05 +0800)", Getter: func(_ *fasthttp.RequestCtx) string { - return time.Now().Format("02/Jan/2006:15:04:05 +0800") + return time.Now().Format("02/Jan/2006:15:04:05 -0700") }, }) @@ -273,13 +273,15 @@ func init() { Name: VarRequestID, Description: "唯一请求标识符", Getter: func(ctx *fasthttp.RequestCtx) string { - // 先从 UserValue 获取,如果没有则生成 + // 先从 UserValue 获取,如果没有则生成并缓存 if v := ctx.UserValue(VarRequestID); v != nil { if s, ok := v.(string); ok { return s } } - return uuid.New().String() + id := uuid.New().String() + ctx.SetUserValue(VarRequestID, id) + return id }, }) } diff --git a/internal/variable/variable.go b/internal/variable/variable.go index ebc50d3..7834ac0 100644 --- a/internal/variable/variable.go +++ b/internal/variable/variable.go @@ -117,7 +117,12 @@ func NewContext(ctx *fasthttp.RequestCtx) *Context { vc, ok := pool.Get().(*Context) if !ok { // 池中类型不正确时返回新 Context - return &Context{ctx: ctx} + return &Context{ + ctx: ctx, + store: make(map[string]string), + cache: make(map[string]string), + bytesCache: make(map[string][]byte), + } } vc.ctx = ctx vc.status = 0