新增功能: - stream 模块: 流式传输支持,优化大文件和实时数据传输 - Goroutine 池: 限制并发数量,减少调度开销 - 优雅升级: 零停机热升级,继承父进程监听器 - sendfile: 零拷贝文件传输,大文件直接从内核传输 重构改进: - App 结构体封装,支持热升级和信号处理 - 配置结构字段对齐和代码清理 - 完善错误处理和日志记录 Co-Authored-By: Claude <noreply@anthropic.com>
58 lines
1.2 KiB
Go
58 lines
1.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
// StaticHandler 静态文件处理器
|
|
type StaticHandler struct {
|
|
root string
|
|
index []string
|
|
}
|
|
|
|
// NewStaticHandler 创建静态文件处理器
|
|
func NewStaticHandler(root string, index []string) *StaticHandler {
|
|
return &StaticHandler{root: root, index: index}
|
|
}
|
|
|
|
// Handle 处理静态文件请求
|
|
func (h *StaticHandler) Handle(ctx *fasthttp.RequestCtx) {
|
|
path := string(ctx.Path())
|
|
|
|
// 安全检查:防止目录遍历
|
|
if strings.Contains(path, "..") {
|
|
ctx.Error("Forbidden", fasthttp.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
// 拼接文件路径
|
|
filePath := filepath.Join(h.root, path)
|
|
|
|
// 检查文件/目录是否存在
|
|
info, err := os.Stat(filePath)
|
|
if err != nil {
|
|
ctx.Error("Not Found", fasthttp.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
// 如果是目录,尝试索引文件
|
|
if info.IsDir() {
|
|
for _, idx := range h.index {
|
|
idxPath := filepath.Join(filePath, idx)
|
|
if _, err := os.Stat(idxPath); err == nil {
|
|
fasthttp.ServeFile(ctx, idxPath)
|
|
return
|
|
}
|
|
}
|
|
ctx.Error("Forbidden", fasthttp.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
// 直接返回文件
|
|
fasthttp.ServeFile(ctx, filePath)
|
|
}
|