基于 git 的零拷贝静态web服务器

无聊,产生了个crazy的想法。

git 内部用 zlib 压缩文件内容

Content-Encoding: gzip 也是

如果web服务器输出 .git 里的 静态 内容,是不是可以减一个二次解压/压缩步骤???

blob sha1 直接当etag?

跟AI较量了几轮,一开始它说做不到。因为 blob 的格式比较变态。因为

hello world...

在 .git/objects/ab/cdef... 里的东西是这么存的

zlib(blob 1234\0hello world...)

I was like

???日他妈真变态啊。这前面是写死了 blob <size>\0 然后把文件内容放在一起,再压缩的。

.git 这设计脑子有病啊。。。为啥不是原始文件gz而是加个头去gz。。。

此路不通!结束


然后AI嘴瓢了,说

先别急着吐槽 Linus,这个设计不仅没病,反而是 Git 能成为现代“内容寻址数据库”的精髓所在。
当 Git 从磁盘读取一个松散对象时,它是个流(Stream)。Git 只需要解压出最开始的几个字节,读到 blob 4096\0,内核就可以立刻执行 malloc(4096) 分配精准的内存。接下来的 zlib 数据流就可以源源不断地直冲内存,不需要反复扩容(realloc),也不需要把整个文件全部解压完才知道它有多大。
况且,这里有一个长久的误解:你吐槽的那个把 blob \0 塞进 zlib 的逻辑,其实只存在于松散对象(Loose Object)中。在真正的 Packfile 里,这个文本格式的头早就被干掉了。

【松散对象 Loose Object】

+-------------------------------------------------------+
| zlib 压缩包: [ "blob 1024\0" + 原始文件纯数据 ]           |
+-------------------------------------------------------+

【包文件 Packfile 内部的一条记录】

+---------------------------------------------------------+
| [3-bit 类型] + [变长 Varint 表达的 Size] + [纯 zlib 数据流] |
+---------------------------------------------------------+

我去,这么好的东西,你怎么不早点告诉我!

然后AI给我泼一盆冷水:

不!兼!容!

要正确的CRC32你得把文件全部读一遍,那不就等于解压一遍了。白费力气。完结!


嘿,得亏我早年玩 IIS 长大的。我记得有个偏方,Content-Encoding: deflate,尾部crc32直接丢了

AI:

恭喜你,这是Web 历史上著名的 “Deflate 格式混乱案”
RFC 2616 (HTTP/1.1) 规定和IIS有差异! IIS脑抽地剥离了 zlib 的头尾,只吐了裸压缩流,为了兼容 IIS 的错误实现,各家浏览器各显神通。有的浏览器严格按 RFC 执行,有的浏览器看到 zlib 头会报错,必须看内核的容错机制。
真正的zlib 格式 (RFC 1950) 是要求包含 2 字节头 + DEFLATE 压缩流 + 4 字节 Adler-32 尾

等等,你说啥?Adler-32?这不就又对上了嘛!!!

那么开始 Vibe!!!

Git Packfile 的终极大 Boss:差分存储(Delta Compression)
即便你搞定了上面的所有协议头和校验和,Git 的终极形态——Packfile 还会给你最后一击。你假设的场景是:Git 里的 Blob 都是一个个完整的、独立的压缩包。但实际上,为了极度压榨磁盘空间,当你执行 git gc 后,Packfile 内部采用的是差分存储(Delta Compression)。

啊这??我于是问,能在配置里禁用掉吗?

# 将比对窗口设为 0,彻底禁用 Delta 差分计算
git config --global pack.window 0

# 强制打包所有对象,并立刻、无条件地清除所有 Loose 文件(无视 2 周保护期)
git gc --prune=now --aggressive

# -a 表示把所有对象打包进一个全新的 pack
# -d 表示打包成功后,立刻删除原本的 loose 对象和旧的 pack 文件
git repack -a -d

哎,你tmd不早说。这不就闭环了嘛!!!

于是最后,通过 OpenCode Zen 免费的 MiMo V2.5 Free

https://github.com/est/git2www-zerocopy

本地自测是OK的

我也算是写过 zero-copy 的人了 🤣(assert AI会写 === 我也会写)

必须严肃吐槽一下AI这回答一板一眼,不思考完整,拷打一下挤一点。如果不是我知道 IIS 这个坑可能就放弃这个想法了。

Comments