AssetGateway 是一个面向对象存储的临时访问网关。
它的核心用途是:
复制示例配置并按实际环境修改:
cp config.yaml.example config.yaml
最小配置示例:
server:
listen: ":8080"
host: "https://gateway.example.com"
redis:
addr: "127.0.0.1:6379"
password: ""
db: 0
control:
tokens:
- "control-token-1"
credentials:
s3-prod:
access_key: "your-access-key"
secret_key: "your-secret-key"
buckets:
prod-assets:
bucket: "prod-assets"
region: "ap-guangzhou"
endpoint: "https://cos.ap-guangzhou.myqcloud.com"
credential: "s3-prod"
force_path_style: false
字段说明:
server.listen:服务监听地址server.host:对外访问地址,用于拼接返回给调用方的完整 URLcontrol.tokens:管理接口使用的 Bearer Token 列表credentials:对象存储凭证buckets:可被业务引用的桶别名。接口里传的是别名,不是原始 bucket 名go run . -config config.yaml
curl http://127.0.0.1:8080/healthz
返回:
{
"status": "ok"
}
/token/object/token 下所有接口都需要带 Authorization: Bearer <control-token>/object 下接口只依赖路径里的临时 token,不需要管理令牌X-Request-Id{
"code": "bad_request",
"message": "invalid JSON body",
"request_id": "0f4f8f4d-6d59-4df0-8a5c-f8352d2a8f47"
}
创建一个临时访问令牌。
请求头:
Authorization: Bearer control-token-1 Content-Type: application/json
请求体:
{
"bucket": "prod-assets",
"key": "videos/demo.mp4",
"filename": "demo.mp4",
"method": "GET",
"expire_at": 1760000000,
"max_hits": 3,
"size": -1,
"callback": "https://example.com/webhook/asset"
}
请求字段:
token:可选,自定义令牌;不传则自动生成bucket:必填,桶别名key:必填,对象 keyfilename:可选,下载时用于生成 Content-Dispositionmethod:必填,支持 GET、HEAD、PUTexpire_at:可选,Unix 时间戳秒max_hits:可选,最大命中次数,-1 表示不限制size:可选,上传大小限制,单位字节,-1 表示不限制callback:可选,请求成功后异步回调,必须是 http 或 https默认值:
expire_at:当前时间后 1800 秒max_hits:PUT 默认 1,其他默认 -1size:默认 -1成功响应:201 Created
{
"token": "Y2x2b2xJc2hQOENWQ0trdVV6bE81",
"method": "GET",
"filename": "demo.mp4",
"expire_at": 1760000000,
"url": "https://gateway.example.com/object/Y2x2b2xJc2hQOENWQ0trdVV6bE81"
}
示例:
curl -X POST http://127.0.0.1:8080/token \
-H 'Authorization: Bearer control-token-1' \
-H 'Content-Type: application/json' \
-d '{
"bucket": "prod-assets",
"key": "videos/demo.mp4",
"filename": "demo.mp4",
"method": "GET"
}'
查询令牌详情。
成功响应:200 OK
{
"token": "Y2x2b2xJc2hQOENWQ0trdVV6bE81",
"bucket": "prod-assets",
"key": "videos/demo.mp4",
"filename": "demo.mp4",
"method": "GET",
"expire_at": 1760000000,
"max_hits": -1,
"used_hits": 0,
"size": -1,
"callback": "https://example.com/webhook/asset",
"url": "https://gateway.example.com/object/Y2x2b2xJc2hQOENWQ0trdVV6bE81"
}
查询令牌状态,以及对象当前是否已存在。
成功响应:200 OK
{
"token": "put-token-123",
"bucket": "prod-assets",
"key": "uploads/report.pdf",
"filename": "report.pdf",
"method": "PUT",
"expire_at": 1760000000,
"max_hits": 1,
"used_hits": 0,
"size": 10485760,
"callback": "https://example.com/webhook/asset",
"url": "https://gateway.example.com/object/put-token-123",
"status_url": "https://gateway.example.com/token/put-token-123/status",
"uploaded": true,
"object_exists": true,
"object_size": 83214,
"etag": "6805f2cfc46c0f04559748bb039d69ae"
}
说明:
uploaded 和 object_exists 会是 false删除令牌。
成功响应:204 No Content
使用临时令牌上传对象。
请求体就是文件内容本身,可以直接二进制上传。
示例:
curl -X PUT 'http://127.0.0.1:8080/object/put-token-123' \
-H 'Content-Type: application/pdf' \
--data-binary '@/path/to/report.pdf'
成功响应:200 OK
{
"etag": "6805f2cfc46c0f04559748bb039d69ae",
"size": 83214
}
说明:
size,超出时返回 413 size_exceededPUT token 默认只允许成功上传一次HEAD /object/:token 可用于探测上传结果,不消耗 PUT token 次数使用临时令牌下载对象。
示例:
curl -L 'http://127.0.0.1:8080/object/get-token-123' -o demo.mp4
说明:
filename,响应会带 Content-DispositionRange 请求头used_hits查询对象元信息,不返回文件内容。
示例:
curl -I 'http://127.0.0.1:8080/object/get-token-123'
典型响应头:
HTTP/1.1 200 OK Content-Length: 83214 ETag: 6805f2cfc46c0f04559748bb039d69ae Content-Disposition: attachment; filename="report.pdf"; filename*=UTF-8''report.pdf
说明:
HEAD 不消耗命中次数GET token 和 PUT token 都允许执行 HEAD创建 token 时传入 callback 后,GET、HEAD、PUT 成功完成都会异步发送回调。
回调示例:
{
"event": "asset.access",
"method": "PUT",
"status": 200,
"bucket": "prod-assets",
"key": "uploads/report.pdf",
"size": 83214,
"etag": "6805f2cfc46c0f04559748bb039d69ae",
"range": "",
"client_ip": "127.0.0.1",
"user_agent": "curl/8.7.1",
"referer": "",
"request_id": "0f4f8f4d-6d59-4df0-8a5c-f8352d2a8f47",
"timestamp": 1760000000
}
说明:
asset.access常见 HTTP 状态与 code:
400 bad_request:参数不合法、JSON 格式不合法、bucket 别名不存在、callback 非法401 unauthorized:缺少或格式错误的 Bearer Token403 forbidden:管理令牌校验失败404 token_not_found:token 不存在404 object_not_found:对象不存在405 method_not_allowed:token 不允许当前请求方法409 token_exists:创建时自定义 token 已存在409 hits_exceeded:token 命中次数已用完410 token_expired:token 已过期413 size_exceeded:上传内容超过允许大小502 upstream_error:对象存储请求失败POST /token 创建 GET tokenurlGET /object/:token 下载文件POST /token 创建 PUT tokenurlPUT /object/:token 直接上传文件GET /token/:token/status,或依赖 callback 收到完成通知