生成 multipart/byterange 响应而不扫描发送前的部分

Generating a multipart/byterange response without scanning the parts ahead of sending

我想生成多部分字节范围响应。因为我需要生成多部分边界字符串,所以有没有办法在不扫描我将要发送的每个段的情况下做到这一点?

例如,我可以让用户请求一个字节范围,让我获取并扫描 2GB 的数据,在我的例子中,这涉及我将该数据作为字符串等加载到我的(慢速)VM 中。理想情况下,我想在响应中简单地声明一个部分的长度为一定字节数,然后完成它。是否有任何工具可以为我提供此选项?我看到许多开发人员只是抓住一个 UUID 作为边界,并且可能愿意冒它出现在部件内某处的微小概率的风险,但这个风险似乎足够小,很多人都在接受它?

更详细地解释:提前扫描部件(在生成响应之前)在我的情况下并不可行,因为我需要通过 HTTP 从上游服务获取它们。这意味着我实际上必须首先预取整个部分以计算不匹配的多部分边界,然后才能将该部分拼接到响应中。

假设数据可以是任意的,我不明白如何在不扫描数据的情况下保证没有冲突。

如果数据的格式非常有限(例如...base 64 编码?),您可以选择已知为该格式的非法字节序列的边界。

即使你的boundary确实和数据发生了碰撞,后面一定是header比如Content-Range,这就更不可能了,所以客户端很可能将其视为错误而不是消费错误的数据。

主要的 Web 服务器使用非常简单的策略。 Apache grabs 8 random bytes at startup and renders them in hexadecimal. nginx uses a sequential counter left-padded 带零。

UUID 旨在避免与其他 UUID 发生冲突,而不是与任意数据发生冲突。与相同长度的完全随机字符串相比,UUID 不太可能成为好的边界。此外,某些 UUID 变体包含您可能不想透露的信息,例如您机器的 MAC 地址。

Ideally I would like to simply state in the response that a part has a length of a certain number of bytes, and be done with it. Is there any tooling that could provide me with this option?

也许您可以避免支持多个范围,而只是告诉客户分别请求每个范围。那样的话,你不用multipart格式,就没有问题了。

如果您确实想在一个响应中发送多个范围,则 RFC 7233 需要多部分格式,这需要边界字符串。

当然,您可以发明自己的机制而不是 RFC 7233 的机制。在这种情况下:

  • 您不能使用 206 (Partial Content)。您必须使用 200(正常)或其他一些适用的状态代码。
  • 您不能使用 multipart/byteranges 媒体类型。您必须提出自己的媒体类型。
  • 您不能使用 Range 请求 header。
  • 因为对 GET 请求的 200(OK)响应是 supposed to carry a (full) representation of the resource,您必须执行以下操作之一:
    • 在URL中对请求的范围进行编码;或
    • 使用类似 POST 的东西代替 GET;或
    • 使用自定义 non-standard 状态代码而不是 200(好的);或
    • (不确定这是否正确)使用媒体类型参数,将它们发送到 Accept, and add Accept to Vary.

chunked transfer coding 可能有用,但您不能单独依赖它,因为它是连接的 属性,而不是负载。