- file domains are created, queried, sized and deleted by the file service (POST/GET/DELETE /file/v1/domains), with per-domain quota enforced on write - /file/v1/options publishes the quota choices; nothing about files lives on the host any more - tickets carry the issuing space and a unique id: a domain only accepts tickets from its own space, and read/delete tickets work once (no replaying a counted download) - uploads stay pending until the client confirms them; abandoned ones are swept after 24h, and an upload ticket can cancel its own bytes - backup target is S3 (SigV4 client, no SDK) instead of WebDAV - CORS allows the methods the browser really uses (POST, DELETE) and exposes Retry-After
39 lines
2.0 KiB
C#
39 lines
2.0 KiB
C#
using WebDrop.FileProtocol;
|
|
using WebDrop.Sync;
|
|
|
|
namespace WebDrop.FileApi;
|
|
|
|
/// <summary>配置节 "FileApi"。环境变量形式:FileApi__DataDir、FileApi__Secret ……</summary>
|
|
public sealed class FileApiOptions
|
|
{
|
|
public string DataDir { get; set; } = "files-data";
|
|
|
|
/// <summary>和主后端共用的密钥(主后端的 WebDrop:Files:Secret),至少 32 个字符</summary>
|
|
public string Secret { get; set; } = "";
|
|
|
|
/// <summary>前端所在的源;浏览器直接把文件传给这里,必须列出,否则不发 CORS 头</summary>
|
|
public string[] CorsOrigins { get; set; } = [];
|
|
|
|
/// <summary>创建频道时可以分配的文件空间档位(字节);不配置用内置的 1/5/10/50/100 GiB。默认值不放在数组里:配置绑定会把数组按下标合并进默认值</summary>
|
|
public long[] QuotaChoices { get; set; } = [];
|
|
|
|
/// <summary>创建频道时不选择的默认文件空间,必须是档位之一</summary>
|
|
public long DefaultQuota { get; set; } = 10L << 30;
|
|
|
|
public FileDomainOptions Domain => new(EffectiveChoices, DefaultQuota);
|
|
|
|
public long[] EffectiveChoices => QuotaChoices.Length == 0 ? FileDomainOptions.Fallback.QuotaChoices : QuotaChoices.Where(n => n > 0).Distinct().Order().ToArray();
|
|
|
|
/// <summary>上传了字节、却一直没有被确认(没有登记到主后端)的条目,过多少小时删掉。默认 24</summary>
|
|
public int PendingRetentionHours { get; set; } = 24;
|
|
|
|
/// <summary>磁盘上最多存这么多字节,0 表示不限。满了拒绝新的帧(507),已有的不受影响</summary>
|
|
public long MaxStoreBytes { get; set; }
|
|
|
|
/// <summary>一帧的最大字节数:26 字节头部 + 最大负载(1 MiB + 16 字节标签)</summary>
|
|
public int MaxFrameBytes { get; set; } = 26 + (1 << 20) + 16;
|
|
|
|
/// <summary>每天把新增的文件帧同步到外部存储(S3 协议)。已删除的内容在备份里再留 RetainDays 天</summary>
|
|
public DailyBackupOptions Backup { get; set; } = new() { Time = "04:30" };
|
|
}
|