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
This commit is contained in:
xfy 2026-06-11 16:22:55 +08:00
parent b766b98125
commit 818aa23739
4 changed files with 24 additions and 10 deletions

View File

@ -142,9 +142,15 @@ func getOutput(path string) io.Writer {
func (l *Logger) LogAccess(ctx *fasthttp.RequestCtx, status int, size int64, duration time.Duration) { func (l *Logger) LogAccess(ctx *fasthttp.RequestCtx, status int, size int64, duration time.Duration) {
// JSON 格式或空格式:输出结构化 JSON // JSON 格式或空格式:输出结构化 JSON
if l.accessFormat == formatJSON || l.accessFormat == "" { 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(). l.accessLog.Info().
Str("remote_addr", netutil.FormatRemoteAddr(ctx)). Str("remote_addr", netutil.FormatRemoteAddr(ctx)).
Bytes("request", append(append(ctx.Method(), ' '), ctx.Path()...)). Bytes("request", req).
Int("status", status). Int("status", status).
Int64("body_bytes_sent", size). Int64("body_bytes_sent", size).
Dur("request_time", duration). Dur("request_time", duration).

View File

@ -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 == "" { if mimeType == "" {
defaultMutex.RLock() defaultMutex.RLock()
mimeType = defaultMIME mimeType = defaultMIME
defaultMutex.RUnlock() defaultMutex.RUnlock()
} }
// 插入新条目
entry := &mimeCacheEntry{ext: ext, mimeType: mimeType}
entry.element = mimeLRU.PushFront(entry)
mimeCache[ext] = entry
return mimeType return mimeType
} }

View File

@ -255,7 +255,7 @@ func init() {
Name: VarTimeLocal, Name: VarTimeLocal,
Description: "本地时间格式02/Jan/2024:15:04:05 +0800", Description: "本地时间格式02/Jan/2024:15:04:05 +0800",
Getter: func(_ *fasthttp.RequestCtx) string { 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, Name: VarRequestID,
Description: "唯一请求标识符", Description: "唯一请求标识符",
Getter: func(ctx *fasthttp.RequestCtx) string { Getter: func(ctx *fasthttp.RequestCtx) string {
// 先从 UserValue 获取,如果没有则生成 // 先从 UserValue 获取,如果没有则生成并缓存
if v := ctx.UserValue(VarRequestID); v != nil { if v := ctx.UserValue(VarRequestID); v != nil {
if s, ok := v.(string); ok { if s, ok := v.(string); ok {
return s return s
} }
} }
return uuid.New().String() id := uuid.New().String()
ctx.SetUserValue(VarRequestID, id)
return id
}, },
}) })
} }

View File

@ -117,7 +117,12 @@ func NewContext(ctx *fasthttp.RequestCtx) *Context {
vc, ok := pool.Get().(*Context) vc, ok := pool.Get().(*Context)
if !ok { if !ok {
// 池中类型不正确时返回新 Context // 池中类型不正确时返回新 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.ctx = ctx
vc.status = 0 vc.status = 0