transfer.sh的隐藏能力:多文件zip合并下载与浏览器预览页源码剖析
【免费下载链接】transfer.shEasy and fast file sharing from the command-line.项目地址: https://gitcode.com/gh_mirrors/tr/transfer.sh
transfer.sh 是一款命令行极速文件分享工具,一条 curl 命令即可上传并生成可下载链接。除了最常用的上传功能外,它还藏着两个"隐藏能力":多文件 zip 合并下载(服务端把多个文件实时打包成一个压缩包)和浏览器智能预览页(图片、视频、Markdown 直接在浏览器中渲染)。这篇文章带你快速上手这两个功能,并深入源码剖析它的实现原理。
一、多文件 zip 合并下载:一个 URL 打包多个文件 📦
上传多文件的两种方式
先把文件传到服务器。transfer.sh 支持两种上传姿势:
- curl PUT 单文件上传:
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt $ curl --upload-file ./hello2.txt https://transfer.sh/hello2.txt- POST 表单一次传多个文件(见 examples.md):
$ curl -i -F filedata=@/tmp/hello.txt -F filedata=@/tmp/hello2.txt https://transfer.sh/上传后你会得到类似https://transfer.sh/15HKz/hello.txt的下载链接,其中15HKz是随机 token。
用 URL 直接触发服务端打包
真正的"隐藏能力"来了:把多个文件路径用逗号放进 URL 的括号里,以.zip结尾,transfer.sh 就会在服务端把它们实时合并成一个压缩包下载(示例来自 examples.md):
# 合并成 zip $ curl https://transfer.sh/(15HKz/hello.txt,15HKz/hello2.txt).zip -o merged.zip # 合并成 tar.gz $ curl https://transfer.sh/(15HKz/hello.txt,15HKz/hello2.txt).tar.gz -o merged.tar.gz支持的格式共有三种:zip、tar、tar.gz。整个过程无需你自己先打包上传,服务器边读取边压缩,直接以流式响应返回。
源码剖析:zipHandler 是如何工作的
三个打包功能的入口路由都注册在 server/server.go:
/(...).zip→zipHandler/(...).tar→tarHandler/(...).tar.gz→tarGzHandler
核心实现在 server/handlers.go 的zipHandler中,流程拆解如下:
| 步骤 | 关键代码 | 说明 |
|---|---|---|
| 1. 解析文件列表 | strings.Split(files, ",") | 把 URL 中逗号分隔的token/filename逐个拆开 |
| 2. 校验元数据 | s.checkMetadata(..., true) | 检查文件是否存在、下载次数/有效期是否用尽(见 handlers.go) |
| 3. 读取存储 | s.storage.Get(...) | 从 local / S3 / GDrive / Storj 等存储后端取文件流 |
| 4. 写入 zip | zw.CreateHeader(header)+io.Copy | 注意Method: zip.Store,采用不压缩的存储模式,保证吞吐速度 |
| 5. 流式响应 | zip.NewWriter(w)直接写 ResponseWriter | 压缩包边生成边发送,不落盘 |
几个值得注意的细节:
- 文件名生成:
transfersh-%d.zip,用纳秒时间戳取uint16片段命名,配合Content-Disposition: attachment头(commonHeader)让浏览器以下载方式保存。 - 容错设计:单个文件元数据校验失败时
continue跳过该文件继续打包,但存储读取失败(文件真不存在)则直接返回 404 终止,避免给出残缺压缩包。 - 计数联动:
checkMetadata第三个参数传true,意味着合并下载同样会计入下载次数,受Max-Downloads头限制。
tarGzHandler(handlers.go)与tarHandler(handlers.go)结构几乎相同,区别只是把archive/zip换成archive/tar,外层再套一层compress/gzip流。
反向操作:上传时把整个目录压成 zip
如果你要分享的是一个目录,官方推荐的是本地打包再上传(README.md):
# 把目录压成 zip 并上传 $ (cd "$file" && zip -r -q - .) | curl --upload-file - https://transfer.sh/目录名.zip # 或管道上传 tar 包 $ tar -czf - /var/log/journal | curl --upload-file - https://transfer.sh/journal.tar.gz二、浏览器预览页:链接不再是"盲下"
预览页长什么样
在浏览器里直接打开一个 transfer.sh 下载链接(而不是 curl 它),你会看到一个精心制作的预览页:
- 图片 / 视频 / 音频:内嵌对应的
<img>/<video>/<audio>播放器; - Markdown 文件:先用 blackfriday 渲染成 HTML,再用 bluemonday 清洗 XSS 后安全展示;
- 纯文本:放进
<pre>标签转义显示; - 页面底部还有二维码、下载按钮和
get/inline两种下载链接。
什么时候显示预览、什么时候直接下载?
路由注册处(server/server.go)用了一个MatcherFunc做"智能分流",判定逻辑是:
客户端
Accept头接受text/html(acceptsHTML)且(没有 Referer,或Referer 路径与当前链接不同)→ 渲染预览页;否则走getHandler直接下载文件。
这个设计很巧妙:
- 你在聊天软件/论坛里点链接→ 无 Referer → 看到预览页,确认内容再下载,安全感拉满;
- 预览页里的"下载"按钮带上了匹配路径的 Referer → 直接开始下载,不会无限套娃;
- curl 等工具的
Accept不含text/html→ 永远直接拿原始文件。
源码剖析:previewHandler 的渲染管线
实现位于 server/handlers.go,核心是一条"按 MIME 类型选模板"的分支链:
image/* → download.image.html video/* → download.video.html audio/* → download.audio.html text/x-markdown → blackfriday 渲染 + bluemonday 清洗 text/plain → <pre> 转义展示 其他 text/* → download.sandbox.html(沙箱 iframe 预览) 其余类型 → download.html(通用下载卡片)其中两个技术亮点:
- 二维码生成:用 go-qrcode 现场把直链编码成 150px 的 PNG,base64 内联进模板——扫码即传,非常适合手机协作场景。
- XSS 双重防线:Markdown 渲染用的是"不安全"模式
blackfriday.Run,但立即过一遍bluemonday.UGCPolicy()白名单过滤;inline下载动作还会对可含 HTML 的 Content-Type 再次做SanitizeReader流式清洗(handlers.go)。
下载链接的两种别名
预览页提供的两个链接对应getHandler的action参数(handlers.go):
/get/{token}/{filename}:Content-Disposition: attachment,强制下载(README.md);/inline/{token}/{filename}:Content-Disposition: inline,在浏览器内联打开。
三、动手试一试:自托管你的 transfer.sh 🚀
想体验全部隐藏功能,最快的方式是 Docker 起一个本地实例(README.md):
docker run --publish 8080:8080 dutchcoders/transfer.sh:latest-noroot --provider local --basedir /tmp/然后:
# 上传两个文件 $ curl --upload-file ./a.txt http://localhost:8080/a.txt # http://localhost:8080/Ab12cd/a.txt $ curl --upload-file ./b.txt http://localhost:8080/b.txt # http://localhost:8080/Xy98zw/b.txt # 一条 URL 合并下载成 zip $ curl "http://localhost:8080/(Ab12cd/a.txt,Xy98zw/b.txt).zip" -o merged.zip再打开浏览器访问上传后返回的链接,就能看到 Markdown 渲染、二维码预览页的完整效果。
小结
| 能力 | URL 形态 | 源码位置 |
|---|---|---|
| 多文件 zip 合并 | /(f1,f2).zip | zipHandler |
| tar / tar.gz 合并 | /(f1,f2).tar(.gz) | tarHandler / tarGzHandler |
| 浏览器智能预览页 | 直接点链接 | previewHandler |
| get / inline 别名 | /get/...、/inline/... | getHandler |
transfer.sh 用不到 200 行的 handler 代码,就把"服务端流式打包 + 浏览器内容嗅探预览"这两件看似复杂的事做成了零配置能力。无论是运维传日志、开发传补丁还是普通用户共享文件,这几个隐藏能力都值得写进你的日常工具箱。
【免费下载链接】transfer.shEasy and fast file sharing from the command-line.项目地址: https://gitcode.com/gh_mirrors/tr/transfer.sh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考