perf(handler): add FileInfo cache to handleTryFiles and handleInternalRedirect
- Check fileInfoCache before os.Stat in handleTryFiles - Check fileInfoCache before os.Stat in handleInternalRedirect - Reduces system calls for try_files scenarios Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3b608be0de
commit
73ef3a938b
@ -396,16 +396,47 @@ func (h *StaticHandler) handleTryFiles(ctx *fasthttp.RequestCtx, reqPath string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件/目录是否存在
|
// 检查文件/目录是否存在
|
||||||
info, err := os.Stat(filePath)
|
// 先查 FileInfo 缓存
|
||||||
if err != nil {
|
var info os.FileInfo
|
||||||
continue // 不存在,尝试下一个
|
var err error
|
||||||
|
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
if cachedInfo, ok := h.fileInfoCache.Get(filePath); ok {
|
||||||
|
info = cachedInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if info == nil {
|
||||||
|
// 缓存未命中,调用 os.Stat
|
||||||
|
info, err = os.Stat(filePath)
|
||||||
|
if err != nil {
|
||||||
|
continue // 不存在,尝试下一个
|
||||||
|
}
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
h.fileInfoCache.Set(filePath, info)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
// 如果是目录,尝试查找索引文件
|
// 如果是目录,尝试查找索引文件
|
||||||
for _, idx := range h.index {
|
for _, idx := range h.index {
|
||||||
idxPath := filepath.Join(filePath, idx)
|
idxPath := filepath.Join(filePath, idx)
|
||||||
if idxInfo, err := os.Stat(idxPath); err == nil && !idxInfo.IsDir() {
|
var idxInfo os.FileInfo
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
if cachedInfo, ok := h.fileInfoCache.Get(idxPath); ok {
|
||||||
|
idxInfo = cachedInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idxInfo == nil {
|
||||||
|
idxInfo, err = os.Stat(idxPath)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
h.fileInfoCache.Set(idxPath, idxInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !idxInfo.IsDir() {
|
||||||
h.serveFile(ctx, idxPath, idxInfo, false)
|
h.serveFile(ctx, idxPath, idxInfo, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -503,11 +534,28 @@ func (h *StaticHandler) handleInternalRedirect(ctx *fasthttp.RequestCtx, targetP
|
|||||||
} else {
|
} else {
|
||||||
filePath = filepath.Join(h.root, targetPath)
|
filePath = filepath.Join(h.root, targetPath)
|
||||||
}
|
}
|
||||||
info, err := os.Stat(filePath)
|
|
||||||
if err != nil {
|
// 先查 FileInfo 缓存
|
||||||
utils.SendError(ctx, utils.ErrNotFound)
|
var info os.FileInfo
|
||||||
return
|
var err error
|
||||||
|
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
if cachedInfo, ok := h.fileInfoCache.Get(filePath); ok {
|
||||||
|
info = cachedInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if info == nil {
|
||||||
|
info, err = os.Stat(filePath)
|
||||||
|
if err != nil {
|
||||||
|
utils.SendError(ctx, utils.ErrNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if h.fileInfoCache != nil {
|
||||||
|
h.fileInfoCache.Set(filePath, info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
utils.SendError(ctx, utils.ErrForbidden)
|
utils.SendError(ctx, utils.ErrForbidden)
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user