Documentation
¶
Overview ¶
uploadpath.go 上传相对路径的统一生成收口。
随机码/令牌生成已上收至 github.com/oekit/kitx/uidgen(2026-10-05 起); 上传相对路径 uploads/YYYY/MM/DD/ 的拼接逻辑保留在此。
Index ¶
- Variables
- func AllExpireStyles() []string
- func CalculateExpireCount(expireStyle string, expireValue int) int
- func CalculateExpireTime(expireValue int, expireStyle string) *time.Time
- func CheckExpireStyleAllowed(style string) error
- func CheckPassword(hash, pw string) bool
- func CheckUploadContent(filename string, head []byte) error
- func CheckUploadSize(fileSize, maxSize int64) error
- func CheckWholeFileSize(fileSize int64) error
- func DefaultBlockedExtensions() []string
- func GetAllowedExtensions() []string
- func GetBlockedExtensions() []string
- func GetEnableMagicCheck() bool
- func GetMaxFileSize() int64
- func GetMaxSaveSecondsCap() int64
- func GetMaxUploadSize() int64
- func GetTextShareMaxBytes() int64
- func HashBytes(data []byte) string
- func HashFile(path string) (string, error)
- func HashPassword(pw string) (string, error)
- func HashReader(r io.Reader) (string, error)
- func IsAllowedExtension(filename string) bool
- func IsBlockedExtension(filename string, blacklist []string) bool
- func IsValidExpireStyle(style string) bool
- func MatchBlockedMagic(head []byte) (string, bool)
- func NewFileTooLargeError(limit int64) error
- func NewUploadRelPath(originalName string) (uuidName, rel string)
- func ResolveSharePassword(requireAuth bool, password string) (string, error)
- func SanitizeFileName(name string) string
- func TextPreview(text string) string
- func UploadObjectRelPath(fileName string) string
- func ValidateUsername(name string) error
- type ExpireParams
- type FileTooLargeError
- type MagicMismatchError
Constants ¶
This section is empty.
Variables ¶
DefaultTextShareMaxBytes 文本分享默认上限(对齐上游 222KB)。
var ErrFileTooLarge = errors.New("file size exceeds limit")
ErrFileTooLarge 文件超过允许大小
var ErrFileTypeNotAllowed = errors.New("file type not allowed")
ErrFileTypeNotAllowed 文件类型不允许(黑名单命中或白名单未命中)
var ErrPasswordRequired = errors.New("password required")
ErrPasswordRequired 开启密码保护但未提供密码(调用方映射为 400)。
var ErrTextTooLarge = errors.New("text share exceeds size limit")
ErrTextTooLarge 文本分享超过大小上限
Functions ¶
func AllExpireStyles ¶ added in v0.27.1
func AllExpireStyles() []string
AllExpireStyles 返回全部合法过期样式(**有序**,便于前端渲染与对账)。
2026-10-22:这是「过期样式合法集合」的**唯一真相源**。此前 setup_service.go / app/mcp/tools.go / bootstrap/handlers_public.go 各有一份独立白名单,**三份都漏了 "count"**(按取件次数过期)⇒ 管理员勾了会被静默丢弃、前端根本选不到、MCP 判非法——同一能力四种行为。 新增/调整样式只改这一处。
func CalculateExpireCount ¶
CalculateExpireCount 计算过期次数(-1 表示无限制)
func CalculateExpireTime ¶
CalculateExpireTime 计算过期时间。 全局上限钳制:upload.max_save_seconds_cap > 0 且时长超过上限时钳到上限 (此前该配置定义了但无任何调用方,形同虚设)。
func CheckExpireStyleAllowed ¶
CheckExpireStyleAllowed 过期样式白名单校验(对标上游"管理员裁剪过期样式")。 upload.allowed_expire_styles 为空 = 全部允许;否则样式必须在列表内。 空样式 = 未指定(历史语义,下游 CalculateExpireTime 会默认 day),放行。
func CheckPassword ¶
CheckPassword 校验密码。 空 hash 一律拒绝:启用密码保护的分享若哈希缺失(配置错误/历史脏数据), 不允许任何密码(包括空密码)通过——防止"空哈希绕过"。
func CheckUploadContent ¶
CheckUploadContent 组合校验:扩展名准入(白/黑名单)+ 魔数。
- IsAllowedExtension(白名单未命中 / 黑名单命中)→ 拒绝
- 魔数命中(开关 upload.enable_magic_check 开、head 非空、扩展名不在 skip 列表)→ 拒绝 防"jpg.exe 改名 cat.jpg"
head 可为 nil(调用方拿不到内容头时只做扩展名检查)。
func CheckUploadSize ¶
CheckUploadSize 校验文件大小是否超限。 maxSize <= 0 表示不限制。
func CheckWholeFileSize ¶
CheckWholeFileSize 整文件大小上限校验(upload.max_file_size,0=不限)。 分片/presign 直传等"整文件"通道用本函数;与单请求体上限 GetMaxUploadSize 区分。
func DefaultBlockedExtensions ¶
func DefaultBlockedExtensions() []string
DefaultBlockedExtensions 返回内置默认黑名单扩展名(返回副本,调用方可追加)
func GetAllowedExtensions ¶
func GetAllowedExtensions() []string
GetAllowedExtensions 扩展名白名单(小写)。空 = 未启用白名单。
func GetBlockedExtensions ¶
func GetBlockedExtensions() []string
GetBlockedExtensions 生效的黑名单扩展名:upload.blocked_extensions 非空时用配置, 否则回退内置默认。黑名单永远参与校验(白名单命中也不能豁免)。
func GetEnableMagicCheck ¶
func GetEnableMagicCheck() bool
GetEnableMagicCheck 魔数校验开关(upload.enable_magic_check)。 配置未初始化(测试/启动早期)按开处理,保持历史安全行为。
func GetMaxFileSize ¶
func GetMaxFileSize() int64
GetMaxFileSize 整文件大小上限(分片/预签名/匿名登记通道)。 upload.max_file_size,0 = 不限(分片通道的存在意义即突破单请求限制)。
func GetMaxSaveSecondsCap ¶
func GetMaxSaveSecondsCap() int64
GetMaxSaveSecondsCap 全局过期时间上限(秒),upload.max_save_seconds_cap,0 = 不限。
func GetMaxUploadSize ¶
func GetMaxUploadSize() int64
GetMaxUploadSize 从全局配置获取上传大小上限。 配置未初始化(测试/启动早期)返回 0 表示不限,避免 nil 解引用。
func GetTextShareMaxBytes ¶
func GetTextShareMaxBytes() int64
GetTextShareMaxBytes 文本分享大小上限(字节)。未配置时用默认 222KB。
func HashPassword ¶
HashPassword 用 bcrypt(cost=10) 哈希密码。 空密码返回空字符串(表示"无密码"),不哈希。
func HashReader ¶
HashReader 流式计算 reader 的 SHA-256,返回十六进制字符串。 用于大文件(分片合并后 / 上传落盘后)不占额外内存的完整性指纹。
func IsAllowedExtension ¶
IsAllowedExtension 扩展名准入判定(大小写不敏感),组合白/黑名单:
- 白名单非空:扩展名必须命中白名单,否则拒绝(无扩展名视同未命中)
- 黑名单(可配置,空则用内置默认)永远生效,命中即拒绝——白名单命中也不能豁免
魔数检查不在此函数内,由 CheckUploadContent 编排。
func IsBlockedExtension ¶
IsBlockedExtension 判断文件扩展名是否在黑名单(大小写不敏感)。 无扩展名返回 false。
func IsValidExpireStyle ¶
IsValidExpireStyle 样式是否合法(在已知样式表内)
func MatchBlockedMagic ¶
MatchBlockedMagic 检查内容头部是否命中可执行文件魔数。 head 为文件(或首个分片)的前若干字节。
func NewFileTooLargeError ¶ added in v0.30.5
NewFileTooLargeError 构造整文件超限错误(带业务码 + 动态文案)。
func NewUploadRelPath ¶
NewUploadRelPath 上传相对路径 uploads/YYYY/MM/DD/<uuid><ext>。 单次取时钟构造日期段(避免跨秒边界日期漂移);返回 (唯一文件名, 相对路径)。
func ResolveSharePassword ¶
ResolveSharePassword 分享密码守卫的统一收口: requireAuth=false 返回空哈希;requireAuth=true 时密码为空返回 ErrPasswordRequired,否则返回 bcrypt 哈希(哈希失败返回底层错误)。
func SanitizeFileName ¶
SanitizeFileName 消毒用户提供的原始文件名(展示/存储用):
- 剥离目录成分(/ \ ..),防止路径穿越
- 丢弃控制字符,Windows 保留字符 : * ? " < > | 换下划线
- 去首尾空白与结尾的点(Windows 目录项陷阱)
- 空名/纯符号名回退为 "file"
- 超长按字节截断且保留扩展名
返回值仅用于"展示/存储原始名",磁盘文件名仍由 UUID 生成,双保险。
实现委托 oekit/pkg/pathx.SanitizeFileName(口径见该包文档);本仓只额外 钉死长度上限(120 字节)——磁盘侧按字节卡,多字节文件名不会落盘 ENAMETOOLONG。
func TextPreview ¶ added in v0.32.11
TextPreview 取文本的一行预览(换行/竖线归一为空格,截断到 32 字符 + 省略号)。
用途:**文本分享的展示名**——文本分享没有文件名,取件页展示的就是这段预览 (原先靠 Redis「展示信息快照」携带,2026-10-25 删除该快照后改为从 DB 的 text 字段现算 ⇒ 两处共用本函数,保证「铸造时算的」与「取件时算的」一致)。
func UploadObjectRelPath ¶
UploadObjectRelPath 上传对象的统一相对路径布局:
uploads/YYYY/MM/DD/<uuid><ext>
直传分享落盘与分片合并共用本函数——磁盘名一律 UUID,原始文件名只用于 扩展名推导与展示(消费方存 Text/FileName 字段),路径基变更只改这里。
func ValidateUsername ¶
ValidateUsername 用户名字符集白名单(2026-10-05 审计 P3): 2-32 位,仅字母/数字/下划线/连字符/点。username 进锁定键、限流键、 审计日志与存储路径拼接,收紧字符集防控制字符/超长/同形字符注入。 已有老用户不受影响(仅约束新建)。
Types ¶
type ExpireParams ¶
ExpireParams 过期参数
func ParseExpireParams ¶
func ParseExpireParams(expireValueStr, expireStyle, requireAuthStr string) (*ExpireParams, error)
ParseExpireParams 解析过期参数
type FileTooLargeError ¶ added in v0.30.5
type FileTooLargeError struct{ Limit int64 }
FileTooLargeError 文件超过整文件大小上限(upload.max_file_size)。
带业务码(ErrCode)⇒ handler 的 resp.NewTypedError 透传 CodeTooLarge (HTTP 413)并保留动态文案「文件过大: 最大允许 N 字节」;前端已把 10010 列入动态文案白名单,直接显示后端原文。
2026-10-23 背景:此前各处用 fmt.Errorf("文件过大: ...") 包装 ⇒ 退化成普通 error,业务码丢失——presign init 落 30008「预签名生成失败」,把后端清晰的 文案抹掉(前端按错误码映射覆盖);chunk init 更糟,落 500「服务器内部错误」。
func (*FileTooLargeError) ErrCode ¶ added in v0.30.5
func (e *FileTooLargeError) ErrCode() int
ErrCode 实现 app 侧 typed error 约定(见 pkg/gate.GateError)。
func (*FileTooLargeError) Error ¶ added in v0.30.5
func (e *FileTooLargeError) Error() string
type MagicMismatchError ¶
type MagicMismatchError struct {
Signature string
}
MagicMismatchError 扩展名与内容魔数不符
func (*MagicMismatchError) Error ¶
func (e *MagicMismatchError) Error() string