本文档详细说明如何使用 Silent-NAS 的各种 API 协议。
Silent-NAS 提供标准的 RESTful API 用于文件管理。
- 基础URL:
http://localhost:8080 - 认证: Bearer Token(如启用)
- Content-Type:
application/json或multipart/form-data
POST /api/files/upload
# 示例
curl -X POST \
-F "file=@example.txt" \
http://localhost:8080/api/files/upload
# 响应
{
"file_id": "01JE7XXXXXXXXXXXXXXXXXXXXXC",
"filename": "example.txt",
"size": 1024,
"hash": "sha256:abc123...",
"created_at": "2025-10-21T10:00:00Z"
}GET /api/files/list
# 示例
curl http://localhost:8080/api/files/list
# 带分页
curl "http://localhost:8080/api/files/list?page=1&limit=20"
# 响应
{
"files": [
{
"file_id": "01JE7X...",
"filename": "example.txt",
"size": 1024,
"created_at": "2025-10-21T10:00:00Z"
}
],
"total": 100,
"page": 1,
"limit": 20
}GET /api/files/{file_id}
# 示例
curl http://localhost:8080/api/files/01JE7X... -o downloaded.txt
# Range 请求(断点续传)
curl -H "Range: bytes=0-1023" \
http://localhost:8080/api/files/01JE7X... -o part1.txtHEAD /api/files/{file_id}
# 示例
curl -I http://localhost:8080/api/files/01JE7X...
# 响应头
HTTP/1.1 200 OK
Content-Length: 1024
Content-Type: text/plain
ETag: "abc123..."
Last-Modified: Mon, 21 Oct 2025 10:00:00 GMTDELETE /api/files/{file_id}
# 示例
curl -X DELETE http://localhost:8080/api/files/01JE7X...
# 响应
{
"status": "deleted",
"file_id": "01JE7X..."
}GET /api/files/{file_id}/versions
# 示例
curl http://localhost:8080/api/files/01JE7X.../versions
# 响应
{
"file_id": "01JE7X...",
"versions": [
{
"version_id": "v1",
"size": 1024,
"created_at": "2025-10-21T10:00:00Z"
}
]
}POST /api/files/{file_id}/versions/{version_id}/restore
# 示例
curl -X POST \
http://localhost:8080/api/files/01JE7X.../versions/v1/restoreSilent-NAS v0.7.1 引入了上传会话管理 API,支持大文件的断点续传和秒传功能。
创建一个新的上传会话用于大文件上传:
POST /api/upload-sessions
# 请求体
{
"file_path": "/uploads/large-file.iso",
"total_size": 1073741824
}
# 示例
curl -X POST \
-u admin:admin123 \
-H "Content-Type: application/json" \
-d '{
"file_path": "/uploads/large-file.iso",
"total_size": 1073741824
}' \
http://localhost:8000/api/upload-sessions
# 响应
{
"session_id": "01JDK8PQRS2EXAMPLE",
"file_path": "/uploads/large-file.iso",
"total_size": 1073741824,
"uploaded_size": 0,
"status": "Initializing",
"progress_percent": 0.0,
"memory_usage": 0,
"created_at": "2025-11-28T10:30:00",
"updated_at": "2025-11-28T10:30:00",
"expires_at": "2025-11-30T10:30:00"
}参数说明:
file_path: 上传文件的目标路径total_size: 文件总大小(字节)
响应字段:
session_id: 会话唯一标识符status: 会话状态(Initializing, Uploading, Paused, Completed, Failed, Cancelled)progress_percent: 上传进度百分比memory_usage: 当前内存使用量(字节)expires_at: 会话过期时间(默认24小时)
获取指定会话的详细信息:
GET /api/upload-sessions/{session_id}
# 示例
curl -X GET \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions/01JDK8PQRS2EXAMPLE
# 响应
{
"session_id": "01JDK8PQRS2EXAMPLE",
"file_path": "/uploads/large-file.iso",
"total_size": 1073741824,
"uploaded_size": 268435456,
"status": "Uploading",
"progress_percent": 25.0,
"memory_usage": 8388608,
"created_at": "2025-11-28T10:30:00",
"updated_at": "2025-11-28T10:35:00",
"expires_at": "2025-11-30T10:30:00"
}获取当前用户的所有上传会话:
GET /api/upload-sessions
# 示例
curl -X GET \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions
# 响应
{
"sessions": [
{
"session_id": "01JDK8PQRS2EXAMPLE",
"file_path": "/uploads/large-file.iso",
"total_size": 1073741824,
"uploaded_size": 268435456,
"status": "Uploading",
"progress_percent": 25.0,
"created_at": "2025-11-28T10:30:00",
"expires_at": "2025-11-30T10:30:00"
},
{
"session_id": "01JDK9ABCD3EXAMPLE",
"file_path": "/uploads/another-file.bin",
"total_size": 524288000,
"uploaded_size": 524288000,
"status": "Completed",
"progress_percent": 100.0,
"created_at": "2025-11-28T09:00:00",
"expires_at": "2025-11-30T09:00:00"
}
],
"total": 2
}更新会话状态(如暂停、恢复):
PUT /api/upload-sessions/{session_id}
# 请求体
{
"status": "Paused"
}
# 示例(暂停上传)
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/json" \
-d '{"status": "Paused"}' \
http://localhost:8000/api/upload-sessions/01JDK8PQRS2EXAMPLE
# 示例(恢复上传)
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/json" \
-d '{"status": "Uploading"}' \
http://localhost:8000/api/upload-sessions/01JDK8PQRS2EXAMPLE
# 响应
{
"session_id": "01JDK8PQRS2EXAMPLE",
"file_path": "/uploads/large-file.iso",
"status": "Paused",
"message": "Session status updated successfully"
}支持的状态转换:
Uploading→Paused: 暂停上传Paused→Uploading: 恢复上传Failed→Uploading: 重试上传
删除指定的上传会话:
DELETE /api/upload-sessions/{session_id}
# 示例
curl -X DELETE \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions/01JDK8PQRS2EXAMPLE
# 响应
{
"session_id": "01JDK8PQRS2EXAMPLE",
"message": "Session deleted successfully"
}完整的断点续传工作流程:
# 1. 创建会话
SESSION_ID=$(curl -s -X POST \
-u admin:admin123 \
-H "Content-Type: application/json" \
-d '{"file_path":"/uploads/large.iso","total_size":1073741824}' \
http://localhost:8000/api/upload-sessions \
| jq -r '.session_id')
echo "Session ID: $SESSION_ID"
# 2. 分块上传文件
# 第一块 (0-8MB)
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/octet-stream" \
-H "X-Upload-Session-Id: $SESSION_ID" \
-H "Content-Range: bytes 0-8388607/1073741824" \
--data-binary @large.iso.part1 \
http://localhost:8000/uploads/large.iso
# 第二块 (8MB-16MB)
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/octet-stream" \
-H "X-Upload-Session-Id: $SESSION_ID" \
-H "Content-Range: bytes 8388608-16777215/1073741824" \
--data-binary @large.iso.part2 \
http://localhost:8000/uploads/large.iso
# 3. 查询进度
curl -s -X GET \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions/$SESSION_ID \
| jq '.progress_percent'
# 4. 如果中断,从断点继续
UPLOADED_SIZE=$(curl -s -X GET \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions/$SESSION_ID \
| jq -r '.uploaded_size')
# 从断点继续上传
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/octet-stream" \
-H "X-Upload-Session-Id: $SESSION_ID" \
-H "Content-Range: bytes ${UPLOADED_SIZE}-*/1073741824" \
--data-binary @large.iso.remaining \
http://localhost:8000/uploads/large.iso
# 5. 完成后删除会话
curl -X DELETE \
-u admin:admin123 \
http://localhost:8000/api/upload-sessions/$SESSION_ID通过文件哈希检测重复文件,实现秒传:
# 1. 计算文件哈希
FILE_HASH=$(shasum -a 256 large-file.iso | awk '{print $1}')
FILE_SIZE=$(stat -f%z large-file.iso)
# 2. 带哈希信息上传
curl -X PUT \
-u admin:admin123 \
-H "Content-Type: application/octet-stream" \
-H "X-File-Hash: $FILE_HASH" \
-H "X-File-Size: $FILE_SIZE" \
--data-binary @large-file.iso \
http://localhost:8000/uploads/large-file-copy.iso
# 如果文件已存在,响应头会包含:
# HTTP/1.1 201 Created
# X-Instant-Upload: true
# Content-Length: 0秒传条件:
- 文件哈希完全匹配
- 文件大小一致
- 服务器已存储该文件
| 状态 | 描述 | 可续传 |
|---|---|---|
| Initializing | 会话初始化中 | 否 |
| Uploading | 上传进行中 | 否 |
| Paused | 上传已暂停 | 是 |
| Completed | 上传已完成 | 否 |
| Failed | 上传失败 | 是 |
| Cancelled | 上传已取消 | 否 |
可续传条件:
- 状态为
Paused或Failed - 已上传大小 > 0
- 会话未过期
POST /api/auth/login
# 示例
curl -X POST \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"changeme"}' \
http://localhost:8080/api/auth/login
# 响应
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}# 在请求头中添加 Authorization
curl -H "Authorization: Bearer eyJhbGc..." \
http://localhost:8080/api/files/list# 简单健康检查
curl http://localhost:8080/api/health
# 就绪检查
curl http://localhost:8080/api/health/readiness
# 详细状态
curl http://localhost:8080/api/health/statusWebDAV 让您可以像访问本地文件系统一样访问 Silent-NAS。
- URL:
http://localhost:8081/ - 用户名:
admin(如启用认证) - 密码:
changeme
- 打开 Finder
- 菜单:前往 → 连接服务器(⌘K)
- 输入:
http://localhost:8081 - 输入用户名和密码
- 右键"此电脑" → 映射网络驱动器
- 选择驱动器号
- 文件夹:
http://localhost:8081 - 勾选"使用其他凭据连接"
- 输入用户名和密码
- 打开文件管理器
- 菜单:文件 → 连接到服务器
- 服务器地址:
dav://localhost:8081 - 输入用户名和密码
curl -X PUT -T example.txt \
http://localhost:8081/example.txtcurl -X MKCOL http://localhost:8081/mydir/curl -X PROPFIND \
-H "Depth: 1" \
http://localhost:8081/curl http://localhost:8081/example.txt -o downloaded.txtcurl -X MOVE \
-H "Destination: http://localhost:8081/newpath/example.txt" \
http://localhost:8081/example.txtcurl -X COPY \
-H "Destination: http://localhost:8081/copy.txt" \
http://localhost:8081/example.txtcurl -X DELETE http://localhost:8081/example.txtrclone 是强大的云存储同步工具。
# 交互式配置
rclone config
# 或直接编辑配置文件 ~/.config/rclone/rclone.conf
[silent-nas]
type = webdav
url = http://localhost:8081
vendor = other
user = admin
pass = obscured_password# 列出文件
rclone ls silent-nas:
# 上传文件
rclone copy local_file.txt silent-nas:/
# 下载文件
rclone copy silent-nas:/file.txt ./
# 同步目录
rclone sync ./local_dir/ silent-nas:/remote_dir/
# 挂载为本地文件系统
rclone mount silent-nas:/ /mnt/nasSilent-NAS 提供 S3 兼容的对象存储 API。
- Endpoint:
http://localhost:9000 - Access Key:
minioadmin - Secret Key:
minioadmin - Region:
us-east-1
# macOS
brew install minio/stable/mc
# Linux
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/mc alias set nas http://localhost:9000 minioadmin minioadmin# 创建 bucket
mc mb nas/my-bucket
# 上传文件
mc cp file.txt nas/my-bucket/
# 上传目录
mc cp --recursive ./mydir/ nas/my-bucket/
# 列出 bucket
mc ls nas/
# 列出文件
mc ls nas/my-bucket/
# 下载文件
mc cp nas/my-bucket/file.txt ./
# 删除文件
mc rm nas/my-bucket/file.txt
# 删除 bucket
mc rb nas/my-bucket
# 同步目录
mc mirror ./local_dir/ nas/my-bucket/remote_dir/# macOS
brew install awscli
# Linux
pip install awscliaws configure set aws_access_key_id minioadmin
aws configure set aws_secret_access_key minioadmin
aws configure set region us-east-1
# 设置 endpoint
export S3_ENDPOINT=http://localhost:9000# 列出 bucket
aws s3 ls --endpoint-url $S3_ENDPOINT
# 创建 bucket
aws s3 mb s3://my-bucket --endpoint-url $S3_ENDPOINT
# 上传文件
aws s3 cp file.txt s3://my-bucket/ --endpoint-url $S3_ENDPOINT
# 列出文件
aws s3 ls s3://my-bucket/ --endpoint-url $S3_ENDPOINT
# 下载文件
aws s3 cp s3://my-bucket/file.txt ./ --endpoint-url $S3_ENDPOINT
# 删除文件
aws s3 rm s3://my-bucket/file.txt --endpoint-url $S3_ENDPOINT
# 同步目录
aws s3 sync ./local_dir/ s3://my-bucket/remote_dir/ --endpoint-url $S3_ENDPOINT# 安装
pip install s3cmd
# 配置
cat > ~/.s3cfg << EOF
[default]
access_key = minioadmin
secret_key = minioadmin
host_base = localhost:9000
host_bucket = localhost:9000/%(bucket)
use_https = False
EOF# 创建 bucket
s3cmd mb s3://my-bucket
# 上传文件
s3cmd put file.txt s3://my-bucket/
# 列出文件
s3cmd ls s3://my-bucket/
# 下载文件
s3cmd get s3://my-bucket/file.txt
# 删除文件
s3cmd del s3://my-bucket/file.txtgRPC 提供高性能的二进制协议。
- Endpoint:
localhost:50051 - Protocol: gRPC (HTTP/2)
# macOS
brew install grpcurl
# Linux
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest# 列出服务
grpcurl -plaintext localhost:50051 list
# 列出方法
grpcurl -plaintext localhost:50051 list silent.nas.FileService
# 上传文件
grpcurl -plaintext -d '{
"file_id": "test-001",
"data": "SGVsbG8gV29ybGQ="
}' localhost:50051 silent.nas.FileService/UploadFile
# 下载文件
grpcurl -plaintext -d '{"file_id": "test-001"}' \
localhost:50051 silent.nas.FileService/DownloadFileimport grpc
from proto import file_service_pb2, file_service_pb2_grpc
# 创建连接
channel = grpc.insecure_channel('localhost:50051')
stub = file_service_pb2_grpc.FileServiceStub(channel)
# 上传文件
response = stub.UploadFile(file_service_pb2.UploadFileRequest(
file_id='test-001',
data=b'Hello World'
))
print(f"Upload result: {response.success}")
# 下载文件
response = stub.DownloadFile(file_service_pb2.DownloadFileRequest(
file_id='test-001'
))
print(f"Downloaded: {response.data}")在自动同步之外,提供两个管理接口便于联调与运维:
POST /api/admin/sync/push- 请求体:
{ "target": "<grpc_host:port>", "file_ids": ["可选: 指定文件ID数组"] } - 示例:
curl -H 'Content-Type: application/json' \ -d '{"target":"127.0.0.1:50052"}' \ http://127.0.0.1:8080/api/admin/sync/push
POST /api/admin/sync/request- 请求体:
{ "source": "<grpc_host:port>", "file_ids": ["必填: 文件ID数组"] } - 示例:
curl -H 'Content-Type: application/json' \ -d '{"source":"127.0.0.1:50051","file_ids":["01JE..."]}' \ http://127.0.0.1:8080/api/admin/sync/request
说明:若开启认证,以上接口需要管理员权限;未开启认证时默认开放用于内网联调。
# 查看所有 metrics
curl http://localhost:8080/api/metrics
# 主要指标
# - http_requests_total: HTTP 请求总数
# - http_request_duration_seconds: 请求耗时
# - file_operations_total: 文件操作总数
# - file_bytes_transferred: 传输字节数
# - cache_hit_rate: 缓存命中率- 添加 Prometheus 数据源
- 导入 Silent-NAS 仪表盘模板(未来提供)
- 配置告警规则
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 201 | 创建成功 |
| 204 | 删除成功 |
| 206 | 部分内容(Range 请求) |
| 304 | 未修改(缓存有效) |
| 400 | 请求错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 文件不存在 |
| 409 | 冲突 |
| 412 | 前置条件失败 |
| 413 | 文件过大 |
| 500 | 服务器错误 |
{
"error": {
"code": "FILE_NOT_FOUND",
"message": "File not found: 01JE7X...",
"details": {}
}
}# 下载前 1MB
curl -H "Range: bytes=0-1048575" \
http://localhost:8080/api/files/01JE7X... -o part1.bin
# 继续下载剩余部分
curl -H "Range: bytes=1048576-" \
http://localhost:8080/api/files/01JE7X... -o part2.bin
# 合并
cat part1.bin part2.bin > complete.bin# 获取 ETag
ETAG=$(curl -sI http://localhost:8080/api/files/01JE7X... | grep -i etag | cut -d' ' -f2)
# 条件下载(仅在文件变化时下载)
curl -H "If-None-Match: $ETAG" \
http://localhost:8080/api/files/01JE7X... -o file.txt# 批量上传
for file in *.txt; do
curl -X POST -F "file=@$file" http://localhost:8080/api/files/upload
done
# 使用 rclone 同步整个目录
rclone sync ./local_dir/ silent-nas:/remote_dir/ls *.jpg | parallel -j 10 \
'curl -X POST -F "file=@{}" http://localhost:8080/api/files/upload'