news 2026/9/21 18:33:33

transfer.sh的隐藏能力:多文件zip合并下载与浏览器预览页源码剖析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
transfer.sh的隐藏能力:多文件zip合并下载与浏览器预览页源码剖析

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 支持两种上传姿势:

  1. curl PUT 单文件上传
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt $ curl --upload-file ./hello2.txt https://transfer.sh/hello2.txt
  1. 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:

  • /(...).zipzipHandler
  • /(...).tartarHandler
  • /(...).tar.gztarGzHandler

核心实现在 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. 写入 zipzw.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(通用下载卡片)

其中两个技术亮点:

  1. 二维码生成:用 go-qrcode 现场把直链编码成 150px 的 PNG,base64 内联进模板——扫码即传,非常适合手机协作场景。
  2. XSS 双重防线:Markdown 渲染用的是"不安全"模式blackfriday.Run,但立即过一遍bluemonday.UGCPolicy()白名单过滤;inline下载动作还会对可含 HTML 的 Content-Type 再次做SanitizeReader流式清洗(handlers.go)。

下载链接的两种别名

预览页提供的两个链接对应getHandleraction参数(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).zipzipHandler
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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/21 18:29:12

JVM调优实战:从参数配置到性能优化指南

1. JVM调优实战&#xff1a;从参数配置到性能优化的完整指南在Java应用开发中&#xff0c;JVM调优是每个资深开发者必须掌握的技能。记得我第一次负责生产环境调优时&#xff0c;面对频繁的Full GC和居高不下的CPU使用率&#xff0c;那种手足无措的感觉至今难忘。经过多年实践&…

作者头像 李华
网站建设 2026/9/21 18:29:07

VUX 微信端实践:Vue 单页面应用动态设置页面标题的完整方案

VUX 微信端实践&#xff1a;Vue 单页面应用动态设置页面标题的完整方案 【免费下载链接】vux Mobile UI Components based on Vue & WeUI 项目地址: https://gitcode.com/gh_mirrors/vu/vux 本文基于 VUX 仓库官方文档 微信 Vue 单页面应用设置标题 展开。在微信内置…

作者头像 李华
网站建设 2026/9/21 18:26:53

OpenClaw 28万星但配置劝退?TaoToken 一个 Key 统一接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华