# tmp-upload 一个自托管的临时文件分享服务。上传文件后获得一个下载链接,**24 小时后自动删除**。 * Single binary,no runtime dependencies * Built-in web UI (zero external assets) * 10 GB default quota (configurable) * Daily audit log (optional) --- ## 快速开始 ```bash go build -o server . ./server # → 浏览器打开 http://localhost:8080 ``` ```bash # 命令行上传 curl -F "file=@report.pdf" http://localhost:8080/upload # → {"filename":"report.pdf","url":"/download/report-2026-08-27-abc123.pdf","expires_at":"..."} ``` --- ## 配置(命令行 flag) ```text -dir ./data/uploads 上传文件保存目录 -listen :8080 HTTP 监听地址 -ttl 24h 文件过期 TTL -scan 1h 清理扫描间隔 -quota 10737418240 总目录配额(字节,默认 10 GB;0 = 不限) -audit-dir ./data/audit 审计日志目录(每天一个 YYYY-MM-DD.log 文件;空字符串禁用) ``` 示例:把 TTL 改成 1 小时、配额 1 GB: ```bash ./server -ttl 1h -quota 1073741824 ``` --- ## HTTP API | Method | Path | 说明 | |--------|----------------------------|--------------------------------------------| | GET | `/` | Web UI(单 HTML 响应,CSS/JS 经 `/static` 引用) | | POST | `/upload` | 上传文件(`multipart/form-data`,字段名 `file`) | | GET | `/files` | 列出当前未过期文件 | | GET | `/download/:filename` | 下载文件 | | POST | `/download-zip` | 批量下载 (body: `{"files":[...]}`, 最多 100 项) | | POST | `/files-delete` | 批量删除 (body: `{"files":[...]}`, 最多 100 项) | | DELETE | `/files/:filename` | 删除文件 | --- ## 目录结构 ```text tmp-upload/ ├── main.go # 入口、配置、路由注册 (72 行) ├── embed.go # //go:embed + fs.Sub 静态资源 (26 行) ├── audit.go # 审计日志子系统 (102 行) ├── quota.go # 配额管理 + formatSize (112 行) ├── handlers.go # HTTP handlers + DTOs (308 行) ├── batch.go # 批量下载 / 批量删除 handlers (248 行) ├── cleaner.go # TTL 过期清理 (57 行) ├── audit_test.go # audit 单元测试 ├── security_test.sh # HTTP 端到端测试 ├── go.mod / go.sum └── static/ ├── index.html.tpl # HTML 骨架 (经 /static 引用 CSS/JS, 含批量删除按钮) ├── app.css # CSS (359 行) ├── app.js # JS — 主程序 (443 行) ├── helpers.js # JS — 纯函数 + 倒计时 (58 行) └── batch.js # JS — 批量选择 / 批量下载 / 批量删除 (119 行) ``` ### 单文件部署说明 `embed.go` 用 `//go:embed` 把 `static/` 下的 CSS/JS 编入二进制, 在 `init()` 中用 `fs.Sub` 切出 `static/` 子文件系统供 `/static` 路由对外提供; HTML 骨架 `index.html.tpl` 单独 embed,`GET /` 直接返回。 浏览器加载的是拆分请求(HTML + `` CSS + `