lolly/internal/handler/sendfile.go
xfy d269940d8b style: fix formatting issues
- Add missing newlines at end of files
- Fix indentation in ssl.go
- Remove extra blank lines

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 13:42:53 +08:00

80 lines
2.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build !linux
// Package handler 提供 HTTP 请求处理器,包括路由、静态文件服务和零拷贝传输。
//
// 该文件包含非 Linux 平台的 sendfile 实现(使用 fallback 方式)。
//
// 作者xfy
package handler
import (
"os"
"syscall"
"github.com/valyala/fasthttp"
)
// SendFile 零拷贝文件传输。
//
// 大文件使用系统调用直接从文件传输到 socket避免用户空间拷贝
// 从而减少 CPU 和内存开销,提升传输性能。
//
// 参数:
// - ctx: fasthttp 请求上下文,用于获取底层连接
// - file: 要传输的文件对象
// - offset: 文件起始偏移量(字节)
// - length: 传输长度(字节),-1 表示传输到文件末尾
//
// 返回值:
// - error: 传输过程中的错误
//
// 注意事项:
// - 小于 8KB 的文件使用普通 io.Copy
// - 非 Linux 平台macOS、Windows使用 fallback 方式
//
// 使用示例:
//
// file, _ := os.Open("large_file.bin")
// defer file.Close()
// info, _ := file.Stat()
// err := SendFile(ctx, file, 0, info.Size())
func SendFile(ctx *fasthttp.RequestCtx, file *os.File, offset, length int64) error {
// 小文件使用普通 io.Copy
if length < MinSendfileSize {
return copyFile(ctx, file, offset, length)
}
// 尝试获取 socket 文件描述符
conn := getNetConn(ctx)
if conn == nil {
return copyFile(ctx, file, offset, length)
}
// 非 Linux 平台使用 fallback
err := platformSendfile(conn, file, offset, length)
if err != nil {
// sendfile 失败fallback 到 io.Copy
return copyFile(ctx, file, offset, length)
}
return nil
}
// platformSendfile 非 Linux 平台的 sendfile 实现。
//
// macOS 和 Windows 不支持 sendfile 系统调用,返回 ENOTSUP 触发 fallback。
//
// 参数:
// - conn: 目标网络连接
// - file: 源文件对象
// - offset: 文件起始偏移量
// - length: 传输长度
//
// 返回值:
// - error: 始终返回 ENOTSUP表示不支持
func platformSendfile(conn any, file *os.File, offset, length int64) error {
// macOS sendfile 签名复杂,简化使用 fallback
// Windows TransmitFile 需要特殊 API
return syscall.ENOTSUP
}