← 返回工具列表

golocaldownload

把一个服务器目录,变成可浏览、可检索、可下载的文件站

  • 语言: Go 1.23+
  • 许可证: MIT
  • 平台: 15 个平台(Windows / Linux / macOS / FreeBSD)

技术栈

  • Go
  • Gin
  • 内嵌静态资源
  • Bootstrap 5
  • Docker

概览

golocaldownload 把一个服务器目录变成可浏览、可检索、可下载的文件站。它用 Go + Gin 写成,页面模板、静态资源和配置模板全部通过 //go:embed 内嵌,发布出去就是单个可执行文件 —— 解压即用,不需要 Node、不需要反向代理、不需要数据库。

适合把构建产物、素材包或内部资料挂到一个简单 URL 后面:本机或内网打开即用。

功能

  • 目录浏览:面包屑逐级跳转,目录排在文件前面,展示大小与修改时间
  • 按类型显示图标:压缩包 / 图片 / 视频 / 音频 / 文档 / 表格 / 代码按扩展名区分,未知扩展名回落通用文档图标
  • 全局检索:按文件名忽略大小写子串匹配,可一键定位到文件所在目录,最多返回 500 条
  • 文件下载:中文、空格等非 ASCII 文件名按 RFC 5987 编码,浏览器不会存成乱码
  • 一键复制地址:文件复制绝对下载地址(浏览器、wget、下载工具都能直接吃),目录复制定位页面地址
  • 主题切换:亮色 / 跟随系统 / 暗色三态,首帧就应用主题,暗色下不闪白屏
  • 列表 / 网格双视图:列表看大小与时间,网格按图标认内容;切换不重新请求接口
  • 越界防护:列表、检索、下载都限制在下载库之内,../ 目录穿越直接拒绝
  • 优雅退出:Ctrl+C 或 SIGTERM 会等待在途下载收尾,不掐断大文件传输

快速开始

需要 Go 1.23 及以上。

# 开发模式直接跑
go run .

# 或编译后运行
go build -o golocaldownload . && ./golocaldownload

启动后会打印版本、配置来源、下载库目录与可访问地址:

golocaldownload dev(debug)
配置来源: config/env.ini
下载库目录: E:\download_lib
本机访问: http://127.0.0.1:9801
局域网访问: http://192.168.1.10:9801

把要对外提供的文件丢进「下载库目录」,刷新页面就能看到。默认监听 9801,下载库是运行目录下的 download_lib/(不存在会自动创建)。

部署方式

场景 方式
改代码 / 长期维护 本地源码编译(go build)
直接用 从 Releases 下载对应平台压缩包,解压即跑
有 Docker docker build 本地构建,或用 docker compose up -d
只想拉现成镜像 Docker Hub 或阿里云 ACR 拉取

拉现成镜像最省事:

docker pull tutudev99/golocaldownload:latest
docker run -p 9801:9801 --name golocaldownload \
  -v /home/download_lib:/root/download_lib --restart always -d \
  tutudev99/golocaldownload:latest

挂载路径的右边必须固定写 /root/download_lib,左边按宿主机填。Windows 上用带盘符的路径(如 D:/download_lib),不要写 /home/... —— 那会被当成 Docker Desktop 的 WSL2 虚拟机内部路径,数据不在 Windows 上,资源管理器看不到,重置 Docker Desktop 时还会一起丢。

镜像同时覆盖 linux/amd64 与 linux/arm64,ARM 服务器和 Apple Silicon 可直接跑。

配置

配置文件是 INI 格式,来源优先级从高到低:

  1. -config 参数 / GLD_CONFIG 环境变量指定的文件
  2. 工作目录下的 env.ini
  3. 工作目录下的 config/env.ini
  4. 二进制内嵌的 env.ini.<GLD_ENV>(默认 release)
配置项 默认值 说明
env_mode release debug / release / test
download_lib_path download_lib 下载库目录,支持多级相对或绝对路径,自动创建
display_lib_path 空 页面上展示的下载库路径;留空时自动识别容器映射的宿主机目录
server.http_port 9801 监听端口

二进制内嵌了 env.ini.debug / .local / .release / .test 四份模板,源码 clone 下来直接 go build 即可,不需要先把 env.ini.local 改名。

接口

方法与路径 参数 说明
GET / - 页面
GET /api/list path(相对下载库的路径,留空为根目录) 列出目录内容
POST /api/search 表单 keyword 按文件名检索,最多 500 条
GET /api/download data(文件路径的 base64url 编码) 下载文件

出错时返回对应状态码与 {"error": "..."}:路径越界 400 / 403,目标不存在 404,目录不可读 403,其他 500。

实现要点

  • 所有请求路径都过越界校验:统一走 common.SafeJoin —— 先拒绝含 NUL 的路径,再统一分隔符、清掉首部斜杠,最后用 filepath.Rel 确认结果没逃出根目录;下载接口还额外校验绝对路径也必须在根目录之内
  • 路由常开 Recovery:handler 只返回状态码与错误信息,任何模式下都不会因一次「目录不存在」让进程退出
  • 配置访问带默认值且不会 panic:env_mode 非法时回落 release,GetInt / GetBool / GetDuration 在配置缺失或写错时返回默认值
  • 检索用 filepath.WalkDir 并限制条数:不跟随符号链接,单条目读不到时跳过,上限 500 条避免撑爆响应体
  • 容器里显示宿主机目录:读 /proc/self/mountinfo,按「挂载点是下载库前缀且最长」取记录,用源目录当展示路径
  • 产物可复现:tools/pack 用 Go 标准库显式写入 0755 并固定时间戳,同源码在任何平台、用哪个脚本构建,产物与校验和都一致

已知局限

  1. 没有鉴权 —— 任何能访问端口的人都能浏览与下载全部内容,默认只适合本机或内网
  2. 没有 HTTPS —— 真正的 TLS 需由前置 Nginx / Caddy 之类的反向代理终结
  3. 检索是全量遍历 —— 每次请求都 WalkDir 一遍,下载库特别大时会偏慢
  4. 只支持一个下载库根目录,没有上传、删除、重命名等写操作
  5. 没有断点续传与限速 —— 大文件高并发时容易把带宽打满
  6. Docker 镜像只覆盖 linux/amd64 与 linux/arm64,其余架构请在宿主机直接跑二进制

许可

MIT · 源码:GitHub · 发布页:Releases

最近更新