Help us shape the future of Go! Take the 2026 Go Developer Survey

utils

package
v0.32.41 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

uploadpath.go 上传相对路径的统一生成收口。

随机码/令牌生成已上收至 github.com/oekit/kitx/uidgen(2026-10-05 起); 上传相对路径 uploads/YYYY/MM/DD/ 的拼接逻辑保留在此。

Index

Constants

This section is empty.

Variables

View Source
var DefaultTextShareMaxBytes int64 = 222 * 1024

DefaultTextShareMaxBytes 文本分享默认上限(对齐上游 222KB)。

View Source
var ErrFileTooLarge = errors.New("file size exceeds limit")

ErrFileTooLarge 文件超过允许大小

View Source
var ErrFileTypeNotAllowed = errors.New("file type not allowed")

ErrFileTypeNotAllowed 文件类型不允许(黑名单命中或白名单未命中)

View Source
var ErrPasswordRequired = errors.New("password required")

ErrPasswordRequired 开启密码保护但未提供密码(调用方映射为 400)。

View Source
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

func CalculateExpireCount(expireStyle string, expireValue int) int

CalculateExpireCount 计算过期次数(-1 表示无限制)

func CalculateExpireTime

func CalculateExpireTime(expireValue int, expireStyle string) *time.Time

CalculateExpireTime 计算过期时间。 全局上限钳制:upload.max_save_seconds_cap > 0 且时长超过上限时钳到上限 (此前该配置定义了但无任何调用方,形同虚设)。

func CheckExpireStyleAllowed

func CheckExpireStyleAllowed(style string) error

CheckExpireStyleAllowed 过期样式白名单校验(对标上游"管理员裁剪过期样式")。 upload.allowed_expire_styles 为空 = 全部允许;否则样式必须在列表内。 空样式 = 未指定(历史语义,下游 CalculateExpireTime 会默认 day),放行。

func CheckPassword

func CheckPassword(hash, pw string) bool

CheckPassword 校验密码。 空 hash 一律拒绝:启用密码保护的分享若哈希缺失(配置错误/历史脏数据), 不允许任何密码(包括空密码)通过——防止"空哈希绕过"。

func CheckUploadContent

func CheckUploadContent(filename string, head []byte) error

CheckUploadContent 组合校验:扩展名准入(白/黑名单)+ 魔数。

  • IsAllowedExtension(白名单未命中 / 黑名单命中)→ 拒绝
  • 魔数命中(开关 upload.enable_magic_check 开、head 非空、扩展名不在 skip 列表)→ 拒绝 防"jpg.exe 改名 cat.jpg"

head 可为 nil(调用方拿不到内容头时只做扩展名检查)。

func CheckUploadSize

func CheckUploadSize(fileSize, maxSize int64) error

CheckUploadSize 校验文件大小是否超限。 maxSize <= 0 表示不限制。

func CheckWholeFileSize

func CheckWholeFileSize(fileSize int64) error

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 HashBytes

func HashBytes(data []byte) string

HashBytes 计算字节切片 SHA-256(小内容场景,如分片数据)。

func HashFile

func HashFile(path string) (string, error)

HashFile 计算本地文件 SHA-256(分片合并完成后由 handler 调用,写入 file_codes.file_hash)。

func HashPassword

func HashPassword(pw string) (string, error)

HashPassword 用 bcrypt(cost=10) 哈希密码。 空密码返回空字符串(表示"无密码"),不哈希。

func HashReader

func HashReader(r io.Reader) (string, error)

HashReader 流式计算 reader 的 SHA-256,返回十六进制字符串。 用于大文件(分片合并后 / 上传落盘后)不占额外内存的完整性指纹。

func IsAllowedExtension

func IsAllowedExtension(filename string) bool

IsAllowedExtension 扩展名准入判定(大小写不敏感),组合白/黑名单:

  • 白名单非空:扩展名必须命中白名单,否则拒绝(无扩展名视同未命中)
  • 黑名单(可配置,空则用内置默认)永远生效,命中即拒绝——白名单命中也不能豁免

魔数检查不在此函数内,由 CheckUploadContent 编排。

func IsBlockedExtension

func IsBlockedExtension(filename string, blacklist []string) bool

IsBlockedExtension 判断文件扩展名是否在黑名单(大小写不敏感)。 无扩展名返回 false。

func IsValidExpireStyle

func IsValidExpireStyle(style string) bool

IsValidExpireStyle 样式是否合法(在已知样式表内)

func MatchBlockedMagic

func MatchBlockedMagic(head []byte) (string, bool)

MatchBlockedMagic 检查内容头部是否命中可执行文件魔数。 head 为文件(或首个分片)的前若干字节。

func NewFileTooLargeError added in v0.30.5

func NewFileTooLargeError(limit int64) error

NewFileTooLargeError 构造整文件超限错误(带业务码 + 动态文案)。

func NewUploadRelPath

func NewUploadRelPath(originalName string) (uuidName, rel string)

NewUploadRelPath 上传相对路径 uploads/YYYY/MM/DD/<uuid><ext>。 单次取时钟构造日期段(避免跨秒边界日期漂移);返回 (唯一文件名, 相对路径)。

func ResolveSharePassword

func ResolveSharePassword(requireAuth bool, password string) (string, error)

ResolveSharePassword 分享密码守卫的统一收口: requireAuth=false 返回空哈希;requireAuth=true 时密码为空返回 ErrPasswordRequired,否则返回 bcrypt 哈希(哈希失败返回底层错误)。

func SanitizeFileName

func SanitizeFileName(name string) string

SanitizeFileName 消毒用户提供的原始文件名(展示/存储用):

  • 剥离目录成分(/ \ ..),防止路径穿越
  • 丢弃控制字符,Windows 保留字符 : * ? " < > | 换下划线
  • 去首尾空白与结尾的点(Windows 目录项陷阱)
  • 空名/纯符号名回退为 "file"
  • 超长按字节截断且保留扩展名

返回值仅用于"展示/存储原始名",磁盘文件名仍由 UUID 生成,双保险。

实现委托 oekit/pkg/pathx.SanitizeFileName(口径见该包文档);本仓只额外 钉死长度上限(120 字节)——磁盘侧按字节卡,多字节文件名不会落盘 ENAMETOOLONG。

func TextPreview added in v0.32.11

func TextPreview(text string) string

TextPreview 取文本的一行预览(换行/竖线归一为空格,截断到 32 字符 + 省略号)。

用途:**文本分享的展示名**——文本分享没有文件名,取件页展示的就是这段预览 (原先靠 Redis「展示信息快照」携带,2026-10-25 删除该快照后改为从 DB 的 text 字段现算 ⇒ 两处共用本函数,保证「铸造时算的」与「取件时算的」一致)。

func UploadObjectRelPath

func UploadObjectRelPath(fileName string) string

UploadObjectRelPath 上传对象的统一相对路径布局:

uploads/YYYY/MM/DD/<uuid><ext>

直传分享落盘与分片合并共用本函数——磁盘名一律 UUID,原始文件名只用于 扩展名推导与展示(消费方存 Text/FileName 字段),路径基变更只改这里。

func ValidateUsername

func ValidateUsername(name string) error

ValidateUsername 用户名字符集白名单(2026-10-05 审计 P3): 2-32 位,仅字母/数字/下划线/连字符/点。username 进锁定键、限流键、 审计日志与存储路径拼接,收紧字符集防控制字符/超长/同形字符注入。 已有老用户不受影响(仅约束新建)。

Types

type ExpireParams

type ExpireParams struct {
	ExpireValue int
	ExpireStyle string
	RequireAuth bool
}

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL