Qiniu Kodo native protocol client for MoonBit
Dependencies
fn block_size_reading(size : Int32, last~ : Bool) -> String {
@kodo.check_block_size(size, last~) catch {
_ => return "refused"
}
"ok"
}
test "签名、URL 与边界都在本地算得出,不依赖网络" {
let auth = @kodoauth.Auth::new("ak-example", "sk-example")
let token = auth.upload_token("demo-bucket", key=Some("2026/10/note.txt"))
let decoded = @kodoauth.decode_upload_token(token)
assert_eq(decoded.0, "ak-example")
assert_true(!decoded.1.is_empty())
// 私有下载 URL 的次序承重:先把 `e=<过期时刻>` 拼上,对整串签,最后才拼 `&token=`
let url = auth.private_download_url(
"https://cdn.example.invalid/2026/10/note.txt",
expires=120,
)
assert_true(url.has_prefix("https://cdn.example.invalid/2026/10/note.txt?e="))
assert_true(url.contains("&token=ak-example:"))
// 分块上传路径里的 key 段是 URL-safe Base64(带填充),与 rs 系的 entry 不是同一串
assert_eq(@kodo.v2_key_segment("2026/10/note.txt"), "MjAyNi8xMC9ub3RlLnR4dA==")
assert_eq(
@kodo.encoded_entry("demo-bucket", Some("2026/10/note.txt")),
"ZGVtby1idWNrZXQ6MjAyNi8xMC9ub3RlLnR4dA==",
)
// 除最后一片外每片必须满 1MB:这一档在任何请求发出之前就拒掉,末片不限长
assert_eq(block_size_reading(1024, last=false), "refused")
assert_eq(block_size_reading(1048576, last=false), "ok")
assert_eq(block_size_reading(1, last=true), "ok")
}moon add mldong/moon-kodo| 存储侧要的那一格 | 本 SDK 的件 | 状态 |
|---|---|---|
| 上传(小文件与字节体) | upload_form put_bytes io_post | 已实现 |
| 手动分片五步(第二代 /blocks) | 六个件,见下注 | 已实现 |
| 存在 / 取回 / 删除 | stat open_url delete | 已实现 |
| 同平台复制 / 移动 | copy move_object | 已实现 |
| 单层列举 | list_files(rsf 的 /v2/list) | 已实现 |
| 预签名下载 | Auth::private_download_url(官方只签 GET) | 已实现 |
| 前端直传的凭据 | Auth::upload_token——PUT 那一格由令牌承担,不是预签名 URL | 不适用 |
| 用户元数据 | stat_user_metadata + change_mime | 已实现 |
| 端点与区域 | query_region region_from_probe | 已实现 |
| 对象级 canned ACL | Kodo 协议无这一族 | 不适用 |
| 分块上传第一代(mkfile) | 无对应件 | 待开发 |
| fetch 拉取的任务态轮询 | 有 fetch_path 请求件,无 pfop/jobctrl 那一圈 | 待开发 |
| 建桶 / 删桶 / 桶配置 | 刻意不做,那是控制台的事 | 不适用 |
Install
Download zipQiniu Kodo native protocol client for MoonBit
Dependencies