从 express 的 public 文件夹中提供 git-lfs 文件

Serve git-lfs files from express' public folder

我在 Heroku 上使用 node.js (express),其中 slug size is limited to 300MB.

为了让我的 slug 变小,我想使用 git-lfs 来跟踪我的快递 public 文件夹。

通过这种方式,我的所有资产(图像、视频...)都上传到 lfs-store(比如 AWS S3),git-lfs 离开 a pointer file(可能是 S3 URL在里面?)。

我希望在从 public 文件夹提供文件时快速重定向到远程 S3 文件。

我的问题是我不知道如何从指针文件的内容中检索 URL...

app.use('/public/:pointerfile', function (req, res, next) {
  var file = req.params.pointerfile;
  fs.readFile('public/'+file, function (er, data) {
    if (er) return next(er);

    var url = retrieveUrl(data); // <-- HELP ME HERE with the retrieveUrl function

    res.redirect(url);
  });
});

您不认为快速读取和解析所有 public/* 文件不会太昂贵吗?也许我可以在解析后缓存 URL?

实际上 pointer 文件中不包含任何 url 信息(在您提供的 link 或 here 中可以看出)- 它只为 blob 保留 oid(Object ID),这只是它的 sha256.

然而,您可以使用 oid 和 lfs api that allows you to download specific oids using the batch request.

实现您想要的

您可以从 .git/config 中分辨出用于存储 blob 的端点是什么,它可以接受非默认 lfsurl 标记,例如:

[remote "origin"]
   url = https://...
   fetch = +refs/heads/*:refs/remotes/origin/*
   lfsurl = "https://..."

或单独的

[lfs]
   url = "https://..."

如果没有 lfsurl 标记,那么您正在使用 GitHub 的端点(这可能会重定向到 S3):

Git remote: https://git-server.com/user/repo.git
Git LFS endpoint: https://git-server.com/user/repo.git/info/lfs

Git remote: git@git-server.com:user/repo.git
Git LFS endpoint: https://git-server.com/user/repo.git/info/lfs

但是您应该针对它而不是直接使用 S3,因为 GitHub 的重定向响应也可能包含一些身份验证信息。

检查 batch response 文档以查看响应结构 - 您基本上需要解析相关部分并自行调用以检索 blob(这就是 git lfs 会做的在结帐时代替您。

典型的回复(取自我引用的文档)类似于:

{
   "_links": {
     "download": {
       "href": "https://storage-server.com/OID",
       "header": {
         "Authorization": "Basic ...",
       }
     }
  }
}

因此,您可以 GET https://storage-server.com/OID 使用从批处理响应返回的任何 headers - 最后一步是重命名返回的 blob(它的名称通常是只是 oid,因为 git lfs 使用基于校验和的存储)- 指针文件具有原始资源的名称,因此只需将 blob 重命名为该名称即可。

我终于为此做了一个中间件:express-lfs with a demo here: https://expresslfs.herokuapp.com

在那里你可以下载一个400Mo文件作为证明。

在此处查看用法:https://github.com/goodenough/express-lfs#usage

PS:感谢@fundeldman 在 中提出的好建议 ;)