服务器 路由
路由
createDriveHandler 接收 Request 并返回 Response。网盘的所有路由都位于同一路径下,除了磁盘存储外,没有任何路由传输文件内容:浏览器拿到的是用于发送和读取内容的地址。本页内容
在 Next.js 中
app/api/files/[...path]/route.ts
import { byRoles, createDriveHandler, s3OptionsFrom, s3Storage, sqliteMetadata } from '@rebofiles/server';
import { session } from '@/lib/auth'; // your own
const handle = createDriveHandler({
storage: s3Storage(s3OptionsFrom(process.env)),
metadata: await sqliteMetadata('drive.sqlite'),
identify: async (request) => {
const user = await session(request);
return user ? { id: user.id, admin: user.isAdmin } : null;
},
authorize: byRoles,
secret: process.env.REBOFILES_SECRET!,
base: '/api/files',
});
export { handle as GET, handle as POST, handle as PATCH, handle as PUT, handle as DELETE };在 node:http 上
nodeHandler 会把它变成一个监听器,适用于 node:http、Express 以及基于它们构建的框架。
server.ts
import { createServer } from 'node:http';
import { createDriveHandler, diskStorage, everyone, memoryMetadata, nodeHandler } from '@rebofiles/server';
const handle = createDriveHandler({
storage: diskStorage({ folder: './storage', secret: process.env.REBOFILES_SECRET! }),
metadata: memoryMetadata(),
...everyone(), // only on your own machine: no sign-in, everyone may do everything
secret: process.env.REBOFILES_SECRET!,
base: '/api/files',
});
createServer(nodeHandler(handle)).listen(3000);全部选项
| 选项 | Type | What it does |
|---|---|---|
| storage | Storage | 文件内容存放的位置:s3Storage(s3OptionsFrom(process.env))、gcsStorage(…)、azureStorage(…) 或 diskStorage({ folder, secret })。 |
| metadata | MetadataStore | 条目存放的位置:memoryMetadata()、sqliteMetadata(path) 或 postgresMetadata(pool)。 |
| identify | (request) => User | null | 根据你的会话判断谁在请求;返回 null 时响应 401。{ id, admin: true } 在使用 byRoles 时可以配置网盘。 |
| authorize | (user, action, entry, drive) => boolean | 每条路由都会调用;返回 false 时响应 403。可用 byRoles,或在其外包一层你自己的规则。 |
| secret | string | 用于签名令牌:足够长、随机,并且在每个进程中都相同。 |
| base | string | 所有路由所在的路径:/api/files。 |
| top | 'own' | 'everyone' | “我的文件”根目录显示的内容:每个人自己的(默认),或自己可读的全部内容,适用于整个团队共用一个网盘。 |
| maxSize | number | 可接受的最大文件,单位为字节;默认 5 GiB。 |
| settings | Partial<DriveSettings> | 在有人修改之前使用的默认值:语言、主题、品牌色、图片、quota、trashDays,以及 company:文件收集页面显示的公司名称。 |
| cors | { origins: string[] } | 允许使用这些路由的其他来源页面:桌面窗口、其他域名的页面。 |
| onShare | (event) => void | 每次保存共享时调用,附带共享对象、共享人以及是否为首次共享:用于通知对方。 |
| beforeUpload | (upload, drive) => boolean | void | 在为上传分配地址之前调用,附带名称、类型、大小和文件夹:抛出 Refused 或返回 false 即可拒绝。 |
| inspect | (upload, drive) => boolean | void | 字节到达后、文件列出之前调用,附带读取字节的 read:checkType()、clamav() 或你自己的检查。拒绝时会删除这些字节。 |
| live | false | { poll } | 在 /events 实时告知更改;同一存储上其他进程的更改在 poll 毫秒(2000)内告知。设为 false 则关闭。 |
| derive | Derive | 文件保存后,服务器为页面未生成的内容生成:图片、占位图、文字(PDF、Word 文档、Excel 工作簿;图片需用 ocr())。使用 @rebofiles/server/derive 的 deriveAll()。 |
| onChange | ({ activity, entry }) => void | 对网盘的每一次操作,与动态记录一致:用于 webhook、审计、其他索引或按空间计费。 |
| onComment | ({ comment, entry, mentions, by }) => void | 每条评论,附带用 @ 提到的人:用于通知他们。 |
| onReceived | ({ entry, from, item, request, got }) => void | 通过文件收集收到的每个文件,附带发送者、对应的文件项和目前已收到的内容:用于通知所有者。 |
| onReview | ({ entry, status, reason, from, by }) => void | 每个被接受或退回的文件:用于通知发送者。 |
| reminders | { send(reminder) } | 每隔 remind 天提醒请求的收件人还缺什么,也可立即提醒:mailReminders({ mail: resend(…), url }) 或你自己的实现。 |
| check | false | ({ entry, item, text }) => … | 将收到文件中的文字与其文件项的 words 和 find 比对:默认 checkWritten,可换成你的;false 为不检查。 |
| expiring | false | { field, days, onExpiring } | 文件字段 expires 在 days(15)天内到期时在铃铛中通知所有者,并调用 onExpiring;false 为关闭。 |
| onRead | ({ action, user, link, entries, path }) => void | 每次打开、查看或下载:列出的文件夹、查看或下载的文件、压缩包;由某人或通过链接。用于审计。 |
| people | { search(query, user), names?(ids, user) } | 谁是谁,来自你的目录:共享时与输入匹配的人员和群组及其名称,显示在 id 的位置。 |
| logger | Logger | 记录未在响应中说明的错误:pino(),默认为 console。 |
| onRequest | (done) => void | 每次请求后调用,附带路由、状态、耗时和请求者:用于指标,如 openTelemetry(meter)。 |
| limits | Limits | false | 每人可进行的上传、.zip、文字搜索、链接密码错误和请求次数;超过时返回 429。 |
| limiter | Limiter | limits 计数的存放处:默认在进程内;多个进程时使用 Redis。 |
| clientIp | (request) => string | 请求者的地址,用于同时按地址统计链接密码错误次数。 |
| now | () => Date | 时钟,用于测试。 |
| newId | () => string | 新条目的 id;默认为随机 UUID。 |
保存在内存中
网盘只读取一次并保存在内存中,只有当存储表明它(被本进程或其他进程)修改过时才会重新读取:列出 20,000 个条目的耗时从 36 毫秒降到了 1 毫秒以下。对于一个团队乃至更大规模都绰绰有余;但不适用于数百万个条目。
所有路由
HTTP 路由一页按代码中的定义列出了全部路由。