Files
WebDrop/server/src/WebDrop.Core/Files/IFileGateway.cs
T
justme 72a5e5b839 feat(server): split file storage into a separate file service with tickets, receipts and WebDAV backup
- new projects WebDrop.FileApi (file service), WebDrop.FileProtocol (shared tickets and receipts) and WebDrop.Sync (WebDAV)
- file content of any size goes to the file service; chat, avatars and space structure stay on the main backend
- tickets issued by the main backend, receipts by the file service, deletion queue and daily reconciliation
- daily database snapshot and file sync to external storage (OpenList/WebDAV) with a 30 day retention
- reorganize Core, Storage and Api into feature folders (namespaces unchanged)
- web client uploads file frames to the file service and reads them with tickets
2026-10-17 15:25:16 +08:00

29 lines
1.3 KiB
C#

using WebDrop.FileProtocol;
namespace WebDrop.Core;
/// <summary>给客户端的文件服务入口:地址 + 一张短期票据</summary>
public sealed record FileGrant(string Url, string Ticket, long ExpiresAt);
/// <summary>
/// 主后端和文件服务之间的接口。关闭时(默认)所有帧仍然存在主后端自己的存储里,行为和以前完全一样;
/// 打开后,文件的内容(文件域的对象,不分大小)由客户端直接传给文件服务,主后端只登记元数据和摘要;聊天、头像、目录仍在主后端。
/// </summary>
public interface IFileGateway
{
bool Enabled { get; }
/// <summary>客户端拿到的文件服务根地址(经反向隧道对外的那个)</summary>
string PublicUrl { get; }
FileGrant Issue(FileOp op, Id16 channel, Id16 item, uint from, long nowMs);
bool TryVerifyReceipt(string? token, long nowMs, out FileReceipt receipt);
}
public sealed class NoFileGateway : IFileGateway
{
public static readonly NoFileGateway Instance = new();
public bool Enabled => false;
public string PublicUrl => "";
public FileGrant Issue(FileOp op, Id16 channel, Id16 item, uint from, long nowMs) => throw new WebDropException(ErrorCode.NotFound);
public bool TryVerifyReceipt(string? token, long nowMs, out FileReceipt receipt) { receipt = null!; return false; }
}