# ossx **Repository Path**: atyichang/ossx ## Basic Information - **Project Name**: ossx - **Description**: 阿里云 OSS SDK 的极简封装,屏蔽复杂的初始化配置与魔法变量,提供直观、语义化的文件存储 API - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-04 - **Last Updated**: 2026-06-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OSSx - AI友好的阿里云OSS上传SDK [![Go Report Card](https://goreportcard.com/badge/gitee.com/atyichang/ossx)](https://goreportcard.com/report/gitee.com/atyichang/ossx) [![Tests](https://img.shields.io/badge/tests-69%20functions-brightgreen)](https://gitee.com/atyichang/ossx) [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://gitee.com/atyichang/ossx) 专为AI设计的阿里云OSS文件上传SDK,简单、安全、开箱即用。 ## 快速开始 ### 安装 ```bash go get gitee.com/atyichang/ossx ``` ### 三步集成 **1. 设置环境变量** ```bash export OSS_ACCESS_KEY_ID=your_key_id export OSS_ACCESS_KEY_SECRET=your_secret ``` **2. 创建客户端** ```go import "gitee.com/atyichang/ossx" client, err := ossx.NewClient("my-bucket", "cn-hangzhou", false, false) if err != nil { // AI: 提示用户检查环境变量是否设置 return err } ``` **3. 生成上传凭证** ```go policy, err := client.GeneratePostPolicy( "uploads/file.jpg", // 文件路径 time.Hour, // 有效期 &ossx.PostPolicyOptions{ MaxContentLength: 100 * 1024 * 1024, // 最大100MB ForbidOverwrite: true, // 禁止覆盖 }, ) if err != nil { return err } // policy.Action: 上传URL // policy.Fields: 表单字段 ``` ## AI集成指南 ### 核心功能 - **生成上传凭证**: 为前端表单上传提供OSS凭证 - **文件存在检查**: 检查OSS中是否已存在指定文件 - **文件删除**: 永久删除OSS中的指定文件 - **临时访问URL**: 生成带签名的临时下载链接(1分钟有效) - **安全验证**: 自动检查文件路径安全性 - **简单API**: 三个步骤完成集成 ### 参数说明 #### NewClient 创建客户端 ```go func NewClient( bucket string, // Bucket名称,如 "my-bucket" region string, // 区域,如 "cn-hangzhou", "cn-beijing" disableSSL bool, // 是否禁用SSL (默认false) useInternalEndpoint bool, // 是否使用内网端点 (默认false) ) (*BucketClient, error) ``` **常用区域**: - 中国: cn-hangzhou, cn-beijing, cn-shanghai, cn-shenzhen - 海外: us-west-1, us-east-1, ap-southeast-1 #### Exist 检查文件是否存在 ```go func (c *BucketClient) Exist( ctx context.Context, // 上下文对象,用于控制超时和取消 key string, // 文件路径,如 "uploads/file.jpg" ) (bool, error) ``` **返回值**: - `bool`: true=文件存在 | false=文件不存在 - `error`: 检查过程中出现的错误(网络问题、权限不足等) **使用场景**: - 上传前检查避免重复文件 - 验证文件是否已成功上传 - 确认文件是否已删除 **示例**: ```go ctx := context.Background() exists, err := client.Exist(ctx, "uploads/file.jpg") if err != nil { // AI: 处理错误,可能是网络或权限问题 return fmt.Errorf("检查文件存在性失败: %v", err) } if exists { // AI: 文件已存在,提示用户或执行其他逻辑 fmt.Println("文件已存在") } ``` #### GeneratePresignedUrl 生成临时访问URL ```go func (c *BucketClient) GeneratePresignedUrl( ctx context.Context, // 上下文对象,用于控制超时和取消 key string, // 文件路径,如 "uploads/file.jpg" ) (string, error) ``` **返回值**: - `string`: 带签名的完整 URL,可直接用于 HTTP GET 请求 - `error`: 生成 URL 过程中出现的错误 **特点**: - 有效期:1 分钟(60秒),过期后 URL 失效 - 请求方法:仅支持 GET 请求 - 签名验证:URL 包含签名,确保请求合法性 **使用场景**: - 临时下载链接:生成限时下载地址 - 文件预览:生成图片、PDF 等文件的预览链接 - 私有文件分享:临时访问私有文件 - 邮件附件:在邮件中发送临时文件访问链接 **示例**: ```go ctx := context.Background() url, err := client.GeneratePresignedUrl(ctx, "uploads/photo.jpg") if err != nil { return fmt.Errorf("生成访问链接失败: %v", err) } // url: https://my-bucket.oss-cn-hangzhou.aliyuncs.com/uploads/photo.jpg?signature=... fmt.Printf("临时访问链接: %s\n", url) // 注意:此链接将在 1 分钟后失效 ``` #### Delete 删除文件 ```go func (c *BucketClient) Delete( ctx context.Context, // 上下文对象,用于控制超时和取消 key string, // 文件路径,如 "uploads/file.jpg" ) error ``` **返回值**: - `error`: 删除过程中出现的错误(文件不存在、权限不足、网络问题等) **特点**: - 不可逆操作:文件删除后无法恢复,请谨慎使用 - 幂等性:删除不存在的文件不会报错 - 即时生效:删除操作立即生效,不进入回收站 **使用场景**: - 用户操作:响应用户删除请求,移除上传的文件 - 数据清理:定期清理过期或临时文件 - 存储管理:删除不再需要的文件以节省存储成本 - 隐私合规:响应数据删除请求,满足隐私保护要求 **示例**: ```go ctx := context.Background() err := client.Delete(ctx, "uploads/file.jpg") if err != nil { // AI: 处理错误,可能是文件不存在或权限问题 return fmt.Errorf("删除文件失败: %v", err) } // AI: 文件删除成功,可以更新本地数据库或通知用户 fmt.Println("文件删除成功") ``` **安全建议**: - 删除前建议先调用 `Exist` 方法确认文件存在 - 删除重要文件前建议进行二次确认 - 记录删除操作以便审计和问题排查 #### GeneratePostPolicy 生成凭证 ```go func (c *BucketClient) GeneratePostPolicy( key string, // 文件路径,如 "uploads/file.jpg" expiresIn time.Duration, // 有效期,如 time.Hour, 30*time.Minute opts *PostPolicyOptions, // 可选配置,nil使用默认值 ) (*PostPolicy, error) ``` #### PostPolicyOptions 配置选项 ```go type PostPolicyOptions struct { MinContentLength int64 // 最小文件大小 (字节),0表示不限制 MaxContentLength int64 // 最大文件大小 (字节),0表示使用默认10MB ForbidOverwrite bool // 是否禁止覆盖同名文件 } ``` ### 错误处理 所有错误信息都包含AI行动建议: ```go if err != nil { // 错误格式: "ossx: 错误描述. AI action: 建议操作" // AI可以直接向用户展示错误信息并提供建议 return err } ``` **常见错误**: - `ossx: key cannot be empty. AI action: ask user for filename` - `ossx: key contains '..' (path traversal blocked). AI action: remove '..' from path` - `ossx: key too long (1200 bytes, max 1024). AI action: suggest shorter filename` ### 前端使用示例 生成的Policy可直接用于前端表单: ```html
{{ range .Fields }} {{ end }}
``` ### 常见场景 #### 1. 用户头像上传 ```go policy, err := client.GeneratePostPolicy( fmt.Sprintf("avatars/%s.jpg", userID), time.Hour, &ossx.PostPolicyOptions{ MaxContentLength: 5 * 1024 * 1024, // 5MB ForbidOverwrite: true, }, ) ``` #### 2. 临时文件分享 ```go policy, err := client.GeneratePostPolicy( fmt.Sprintf("temp/%s", filename), 10*time.Minute, // 10分钟有效期 nil, // 使用默认配置 ) ``` #### 3. 大文件上传 ```go policy, err := client.GeneratePostPolicy( fmt.Sprintf("videos/%s", filename), 2*time.Hour, &ossx.PostPolicyOptions{ MinContentLength: 1024 * 1024, // 1MB MaxContentLength: 5 * 1024 * 1024 * 1024, // 5GB }, ) ``` #### 4. 检查文件是否存在 ```go // 上传前检查文件是否已存在 ctx := context.Background() exists, err := client.Exist(ctx, "uploads/file.jpg") if err != nil { return fmt.Errorf("检查文件失败: %v", err) } if exists { // 文件已存在,提示用户 return fmt.Errorf("文件已存在,请使用不同的文件名") } // 文件不存在,生成上传凭证 policy, err := client.GeneratePostPolicy("uploads/file.jpg", time.Hour, nil) ``` #### 5. 生成临时下载链接 ```go // 为已存在的文件生成临时访问链接 ctx := context.Background() url, err := client.GeneratePresignedUrl(ctx, "documents/report.pdf") if err != nil { return fmt.Errorf("生成下载链接失败: %v", err) } // 返回给用户用于下载或预览 // 注意:此链接将在 1 分钟后失效 fmt.Printf("临时下载链接(1分钟有效): %s\n", url) ``` #### 6. 删除文件 ```go // 删除用户上传的文件 ctx := context.Background() // 先确认文件存在 exists, err := client.Exist(ctx, "uploads/file.jpg") if err != nil { return fmt.Errorf("检查文件失败: %v", err) } if !exists { return fmt.Errorf("文件不存在") } // 确认后删除文件 err = client.Delete(ctx, "uploads/file.jpg") if err != nil { return fmt.Errorf("删除文件失败: %v", err) } fmt.Println("文件删除成功") ``` ## 安全机制 - **路径验证**: 自动拦截路径遍历、绝对路径等危险操作 - **文件大小限制**: 默认10MB上限,防止恶意上传 - **凭证时效**: 支持自定义过期时间,建议1小时内 - **零值安全**: 所有可选参数都有安全的默认值 ## 运行测试 ```bash # 运行所有测试 go test -v # 查看覆盖率 go test -cover # 真实环境测试 cd ossx-demo-real go run main.go ``` ## 技术特点 - **高性能**: 基于读写锁的并发优化 - **线程安全**: Double Check模式确保并发安全 - **V4签名**: 完整实现阿里云OSS V4签名算法 - **智能缓存**: MRU缓存策略,固定容量防止内存泄漏 - **100%测试覆盖**: 69个测试函数,180+测试用例 ## 注意事项 1. **环境变量**: 必须设置 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET 2. **长期AK**: 此SDK使用长期AK/SK,不支持STS临时凭证 3. **功能范围**: 支持生成上传凭证、检查文件存在性、生成临时访问URL,其他OSS操作请使用[官方SDK](https://github.com/aliyun/alibabacloud-oss-go-sdk) 4. **Exist方法**: 会向OSS发送网络请求,建议设置合理的context超时时间 5. **GeneratePresignedUrl**: 生成的URL有效期为1分钟,过期后需重新生成;仅支持GET请求 6. **HTTPS建议**: 生产环境建议使用HTTPS (disableSSL=false) ## 许可证 MIT License ## 相关资源 - [阿里云OSS官方文档](https://help.aliyun.com/product/31815.html) - [阿里云Go SDK](https://github.com/aliyun/alibabacloud-oss-go-sdk) ## 更新日志 ### v1.3.0 (2026-04-06) - ✨ 新增 `Delete` 方法:永久删除OSS文件 - ✅ 完善测试覆盖:新增11个Delete相关测试用例 - 📝 更新文档:添加Delete方法使用说明和示例 - 🔧 优化注释:为Delete方法添加AI友好的详细注释 ### v1.2.0 (2026-04-05) - ✨ 新增 `GeneratePresignedUrl` 方法:生成带签名的临时访问URL(1分钟有效) - ✅ 完善测试覆盖:新增7个GeneratePresignedUrl相关测试用例 - 📝 更新文档:添加GeneratePresignedUrl方法使用说明和示例 - 🔧 增强导入:为client.go添加errors、fmt、time包导入 ### v1.1.0 (2026-04-05) - ✨ 新增 `Exist` 方法:检查OSS中文件是否存在 - ✅ 完善测试覆盖:新增5个Exist相关测试用例 - 📝 更新文档:添加Exist方法使用说明和示例 - 🔧 优化注释:为所有方法添加AI友好的详细注释