storage

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrStorageNotInitialized storage 未初始化。
	ErrStorageNotInitialized = errors.New("storage not initialized")
	// ErrPathTraversal 路径穿越被拒绝(C4a)。Delete/Get/Exists/Upload 的相对路径
	// 含 `..` 或绝对路径、逃逸根目录时返回。
	ErrPathTraversal = errors.New("path traversal detected")
	// ErrInvalidPath 路径非法(空、含 NUL 等)。
	ErrInvalidPath = errors.New("invalid path")
	// ErrInvalidFile 上传文件参数非法,例如 nil *multipart.FileHeader。
	ErrInvalidFile = errors.New("invalid file")
	// ErrUploadTooLarge 上传声明大小或实际字节数超过 MaxSizeBytes(P0)。客户端声明的 file.Size
	// 不可信,故除前置校验外,拷贝阶段也按实际字节封顶,防止声明小体积却流式发送大 body 撑爆磁盘/OSS。
	ErrUploadTooLarge = errors.New("upload exceeds max size")
	// ErrReadTooLarge Get 读取内容超过 maxReadBytes 上限(C4c)。与 ErrUploadTooLarge 区分:
	// 前者是读操作的超限,后者是上传操作的超限。
	ErrReadTooLarge = errors.New("read exceeds max size")
)

DefaultStorage 默认存储管理器,包级 facade 代理到它。

主线A 修复:改用 atomic.Pointer 保护读写,消除原裸指针置换(SetDefaultStorageManager) 与 facade 无锁读之间的数据竞争,与 config.defaultManager / database.DefaultRedis 对齐。 类型由 *StorageManager 变更为 atomic.Pointer[StorageManager](breaking:下游若直接 调用 DefaultStorage.Init 等方法需改用 Init 等 facade,或 DefaultStorage.Load().Init)。

Functions

func Delete

func Delete(path string) error

Delete 删除文件

func Exists

func Exists(path string) (bool, error)

Exists 检查文件是否存在。未初始化返回 (false, ErrStorageNotInitialized); 其余语义同 Storage.Exists。

func Get

func Get(path string) ([]byte, error)

Get 获取文件内容

func GetURL

func GetURL(path string) string

GetURL 获取文件访问 URL

func Init

func Init(cfg *config.StorageConfig) error

Init 初始化存储

func SetDefaultStorageManager added in v1.1.0

func SetDefaultStorageManager(m *StorageManager)

SetDefaultStorageManager 提升指定 StorageManager 为全局默认。并发安全(atomic.Store)。

func SetStorage

func SetStorage(s Storage)

SetStorage 设置全局存储实例

func Upload

func Upload(file *multipart.FileHeader, subdir string) (string, error)

Upload 上传文件

func UploadFromBytes

func UploadFromBytes(data []byte, filename, subdir string) (string, error)

UploadFromBytes 从字节数组上传文件

Types

type LocalStorage

type LocalStorage struct {
	// contains filtered or unexported fields
}

LocalStorage 本地存储

func NewLocalStorage

func NewLocalStorage(cfg *config.LocalStorageConfig) *LocalStorage

NewLocalStorage 创建本地存储实例

安全约束:Path 指向的根目录应为框架独占目录,不与用户可控内容混用。 safeJoin 已防 `..` 路径穿越,但若根目录内已存在指向外部的符号链接, Get 会跟随 symlink 读到根外内容——需保证攻击者无法在根目录内创建 symlink。 cfg 为 nil、Path 无法解析或根目录本身是 symlink 时,实例 fail-closed: 后续文件操作返回 ErrStorageNotInitialized。

func (*LocalStorage) Delete

func (s *LocalStorage) Delete(p string) error

Delete 删除文件

func (*LocalStorage) Exists

func (s *LocalStorage) Exists(p string) (bool, error)

Exists 检查文件是否存在。存在返回 (true, nil);不存在返回 (false, nil); 路径非法/穿越返回 (false, err);其他 Stat 错误返回 (false, err)。

func (*LocalStorage) Get

func (s *LocalStorage) Get(p string) ([]byte, error)

Get 获取文件内容。读取受 maxReadBytes 封顶,防止全量读入内存 OOM(C4c)。

func (*LocalStorage) GetURL

func (s *LocalStorage) GetURL(path string) string

GetURL 获取文件访问 URL

func (*LocalStorage) Upload

func (s *LocalStorage) Upload(file *multipart.FileHeader, subdir string) (ret string, err error)

Upload 上传文件

func (*LocalStorage) UploadFromBytes

func (s *LocalStorage) UploadFromBytes(data []byte, filename, subdir string) (ret string, err error)

UploadFromBytes 从字节数组上传文件

type OSSStorage

type OSSStorage struct {
	// contains filtered or unexported fields
}

OSSStorage OSS 存储

func NewOSSStorage

func NewOSSStorage(cfg *config.OSSStorageConfig) (*OSSStorage, error)

NewOSSStorage 创建 OSS 存储实例

func (*OSSStorage) Delete

func (s *OSSStorage) Delete(p string) error

Delete 删除 OSS 文件

func (*OSSStorage) Exists

func (s *OSSStorage) Exists(p string) (bool, error)

Exists 检查 OSS 文件是否存在。存在返回 (true, nil);object 不存在返回 (false, nil); key 非法/穿越返回 (false, err);鉴权/网络/服务端错误返回 (false, err)。

func (*OSSStorage) Get

func (s *OSSStorage) Get(p string) ([]byte, error)

Get 获取 OSS 文件内容。读取受 maxReadBytes 封顶,防止 OOM(C4c)。

func (*OSSStorage) GetSignedURL

func (s *OSSStorage) GetSignedURL(path string, expire time.Duration) (string, error)

GetSignedURL 获取带签名的临时访问 URL(用于私有文件)

func (*OSSStorage) GetURL

func (s *OSSStorage) GetURL(path string) string

GetURL 获取文件访问 URL

func (*OSSStorage) Upload

func (s *OSSStorage) Upload(file *multipart.FileHeader, subdir string) (string, error)

Upload 上传文件到 OSS

func (*OSSStorage) UploadFromBytes

func (s *OSSStorage) UploadFromBytes(data []byte, filename, subdir string) (string, error)

UploadFromBytes 从字节数组上传文件到 OSS

type Storage

type Storage interface {
	Upload(file *multipart.FileHeader, subdir string) (string, error)
	UploadFromBytes(data []byte, filename, subdir string) (string, error)
	GetURL(path string) string
	Delete(path string) error
	Get(path string) ([]byte, error)
	// Exists 检查文件是否存在。存在返回 (true, nil);不存在返回 (false, nil);
	// 未初始化、路径非法/穿越、后端错误返回 (false, err)。
	Exists(path string) (bool, error)
}

Storage 存储接口

func GetStorage

func GetStorage() Storage

GetStorage 获取全局存储实例

type StorageManager added in v1.1.0

type StorageManager struct {
	// contains filtered or unexported fields
}

StorageManager 存储管理器(#10)。照 database.Manager 模式: 实例化 + DefaultStorage 全局默认 + 包级 facade 代理,支持多实例与测试注入。

func NewStorageManager added in v1.1.0

func NewStorageManager() *StorageManager

NewStorageManager 创建存储管理器实例。

func SwapDefaultStorageManager added in v1.4.0

func SwapDefaultStorageManager(m *StorageManager) *StorageManager

SwapDefaultStorageManager 将指定 StorageManager 置为全局默认,并返回被替换的旧 Manager。 旧 Manager 不会被关闭,供 App 初始化这类需要失败回滚的生命周期流程暂存(照 SwapDefaultRedisManager / database.SwapDefaultManager 模式)。nil 被忽略,返回当前默认。

func (*StorageManager) Close added in v1.4.0

func (m *StorageManager) Close() error

Close 释放存储资源,闭合 StorageManager 的 Init/Close 生命周期(与 database/redis/logger manager 对齐,供 App.closeResources 统一调用)。当前 LocalStorage 无可关资源;OSSStorage 的 *oss.Client 未暴露 Close(aliyun-oss-go-sdk),故当前为 no-op。保留此方法为未来驱动 (S3/MinIO/自研等带连接池的驱动)预留收口点:实现了 io.Closer 的 Storage 实现会被自动调用, 框架骨架无需改动。幂等(未初始化或驱动非 io.Closer 时 no-op)。

func (*StorageManager) Get added in v1.1.0

func (m *StorageManager) Get() Storage

Get 返回当前存储实例。

func (*StorageManager) Init added in v1.1.0

func (m *StorageManager) Init(cfg *config.StorageConfig) error

Init 初始化存储

func (*StorageManager) Set added in v1.1.0

func (m *StorageManager) Set(s Storage)

Set 设置存储实例(用于注入 mock 或自定义实现)。

Jump to

Keyboard shortcuts

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