# jdfs2 **Repository Path**: ledao/jdfs2 ## Basic Information - **Project Name**: jdfs2 - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-07 - **Last Updated**: 2025-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JDFS2 - 简化版 S3 兼容服务 > 基于 Go + Gin 的教学版 S3 兼容存储服务,支持核心 API 与 AWS SigV4 鉴权 ## 快速开始 ```bash # 1. 启动服务 make run # 2. 健康检查 curl http://localhost:8000/ping # 3. 运行 SDK 兼容性测试 python tools/s3_test.py # 4. 查看覆盖率报告 make test && open coverage.html ``` ## 项目结构 ``` jdfs2/ ├── internal/ │ ├── api/ # S3 API 路由处理(按功能分类) │ │ ├── buckets/ # 桶操作相关接口 │ │ ├── objects/ # 对象操作相关接口 │ │ ├── multipart/ # 分片上传相关接口 │ │ ├── common/ # 通用类型与错误处理 │ │ └── register.go # 主路由注册入口 │ ├── auth/ # AWS SigV4 鉴权实现 │ ├── service/ # S3 业务逻辑层 │ ├── storage/ # 存储后端(文件系统 + 元数据) │ └── utils/ # S3 错误码与工具函数 ├── tools/ # SDK 测试脚本 └── books/ # 教程文档 ``` ## 常用命令 | 命令 | 说明 | |------|------| | `make run` | 启动服务(默认端口 8000) | | `make restart` | 重启服务(自动清理锁文件) | | `make test` | 运行单元测试与覆盖率分析 | | `make stop` | 停止服务 | | `make clean-lock` | 清理 Badger 数据库锁文件 | 环境变量: - `S3_ROOT`: 数据存储根目录(默认:`runtime/s3-data`) ## 支持的 S3 API ### 🗂️ 桶(Bucket)操作 | 接口 | HTTP 方法 | 路径 | 说明 | |------|-----------|------|------| | **ListBuckets** | `GET` | `/` | 列出所有桶 | | **CreateBucket** | `PUT` | `/:bucket` | 创建桶 | | **HeadBucket** | `HEAD` | `/:bucket` | 检查桶是否存在 | | **DeleteBucket** | `DELETE` | `/:bucket` | 删除桶(需为空) | | **GetBucketLocation** | `GET` | `/:bucket?location` | 获取桶区域信息 | | **GetBucketVersioning** | `GET` | `/:bucket?versioning` | 获取版本控制状态 | | **PutBucketVersioning** | `PUT` | `/:bucket?versioning` | 设置版本控制 | | **GetBucketPolicy** | `GET` | `/:bucket?policy` | 获取桶策略 | | **PutBucketPolicy** | `PUT` | `/:bucket?policy` | 设置桶策略 | | **DeleteBucketPolicy** | `DELETE` | `/:bucket?policy` | 删除桶策略 | | **GetBucketACL** | `GET` | `/:bucket?acl` | 获取访问控制列表 | | **PutBucketACL** | `PUT` | `/:bucket?acl` | 设置访问控制列表 | **示例:创建桶** ```bash curl -X PUT "http://localhost:8000/my-bucket" \ -H "Authorization: AWS4-HMAC-SHA256 ..." ``` ### 📄 对象(Object)操作 | 接口 | HTTP 方法 | 路径 | 说明 | |------|-----------|------|------| | **PutObject** | `PUT` | `/:bucket/*key` | 上传对象 | | **GetObject** | `GET` | `/:bucket/*key` | 下载对象 | | **HeadObject** | `HEAD` | `/:bucket/*key` | 获取对象元数据 | | **DeleteObject** | `DELETE` | `/:bucket/*key` | 删除对象 | | **ListObjectsV2** | `GET` | `/:bucket?list-type=2` | 列举对象(支持分页、前缀过滤) | **ListObjectsV2 查询参数:** - `prefix`: 对象前缀过滤 - `delimiter`: 分隔符(用于目录模拟) - `start-after`: 分页起始位置 - `continuation-token`: 分页令牌 - `max-keys`: 最大返回数量(默认 1000) **示例:上传与下载** ```bash # 上传文件 curl -X PUT --data-binary @file.txt "http://localhost:8000/my-bucket/path/to/file.txt" \ -H "Authorization: AWS4-HMAC-SHA256 ..." # 下载文件 curl "http://localhost:8000/my-bucket/path/to/file.txt" \ -H "Authorization: AWS4-HMAC-SHA256 ..." \ -o downloaded-file.txt ``` ### 🔀 分片上传(Multipart Upload) | 接口 | HTTP 方法 | 路径 | 说明 | |------|-----------|------|------| | **InitiateMultipartUpload** | `POST` | `/:bucket/*key?uploads` | 初始化分片上传 | | **UploadPart** | `PUT` | `/:bucket/*key?partNumber=N&uploadId=ID` | 上传分片 | | **CompleteMultipartUpload** | `POST` | `/:bucket/*key?uploadId=ID` | 完成分片上传 | | **AbortMultipartUpload** | `DELETE` | `/:bucket/*key?uploadId=ID` | 终止分片上传 | **完整流程示例:** ```bash # 1. 初始化上传 UPLOAD_ID=$(curl -X POST "http://localhost:8000/my-bucket/large-file.bin?uploads" \ -H "Authorization: AWS4-HMAC-SHA256 ..." | grep -o '[^<]*' | cut -d'>' -f2) # 2. 上传分片(并发上传) curl -X PUT --data-binary @part1.bin \ "http://localhost:8000/my-bucket/large-file.bin?partNumber=1&uploadId=$UPLOAD_ID" \ -H "Authorization: AWS4-HMAC-SHA256 ..." curl -X PUT --data-binary @part2.bin \ "http://localhost:8000/my-bucket/large-file.bin?partNumber=2&uploadId=$UPLOAD_ID" \ -H "Authorization: AWS4-HMAC-SHA256 ..." # 3. 完成上传 curl -X POST "http://localhost:8000/my-bucket/large-file.bin?uploadId=$UPLOAD_ID" \ -H "Authorization: AWS4-HMAC-SHA256 ..." \ -H "Content-Type: application/xml" \ --data-binary ' 1"etag1" 2"etag2" ' ``` ### 🔐 鉴权与配置 **鉴权方式:** AWS Signature Version 4 - **Access Key**: `AKIAIOSFODNN7EXAMPLE` - **Secret Key**: `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` - **Region**: 任意(推荐 `us-east-1`) **地址风格:** 仅支持 Path-style - ✅ `http://localhost:8000/bucket/key` - ❌ `http://bucket.localhost:8000/key` **SDK 配置示例:** ```python # Python boto3 import boto3 from botocore.config import Config s3 = boto3.client( 's3', endpoint_url='http://localhost:8000', aws_access_key_id='AKIAIOSFODNN7EXAMPLE', aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', region_name='us-east-1', config=Config(s3={'addressing_style': 'path'}) ) ``` ## 错误码对照 | S3 错误码 | HTTP 状态 | 说明 | |-----------|-----------|------| | `NoSuchBucket` | 404 | 桶不存在 | | `NoSuchKey` | 404 | 对象不存在 | | `BucketAlreadyOwnedByYou` | 409 | 桶已存在 | | `BucketNotEmpty` | 409 | 桶非空,无法删除 | | `NoSuchBucketPolicy` | 404 | 桶策略不存在 | | `AccessDenied` | 403 | 鉴权失败 | | `InvalidPart` | 400 | 分片信息错误 | | `NoSuchUpload` | 404 | 上传 ID 不存在 | | `MalformedXML` | 400 | XML 格式错误 | ## 特性与限制 ### ✅ 已实现特性 - 完整的 AWS SigV4 鉴权验证 - 桶与对象的 CRUD 操作 - 分片上传(支持并发上传与断点续传) - ListObjectsV2 分页与前缀过滤 - S3 兼容的 XML 响应格式 - 本地文件系统存储后端 - Badger 数据库存储元数据 ### ⚠️ 教学版限制 - 单机版本,不支持分布式部署 - 暂不支持对象版本控制的完整实现 - 暂不支持生命周期管理 - 暂不支持跨域资源共享(CORS) - 分片上传未强制 5MB 最小限制 ## 开发与测试 **目录结构说明:** - `internal/api/buckets/` - 桶操作接口实现 - `internal/api/objects/` - 对象操作接口实现 - `internal/api/multipart/` - 分片上传接口实现 - `internal/api/common/` - 通用类型与错误处理 - `internal/ginserver/` - HTTP 服务器初始化(仅注册路由) **测试覆盖率:** ```bash make test # 查看 coverage.html 获取详细覆盖率报告 ``` ## 相关文档 - 📖 [完整教程](books/README.md) - 《动手实现 S3 服务》 - 🔧 [API 测试脚本](tools/s3_test.py) - Python SDK 兼容性验证 - 📊 [性能测试](tools/) - 压力测试与性能分析