6

所以,假设我正在编写一个 Web 服务器,并且我想支持“非常大”的文件上传。让我们进一步假设我的意思是通过标准的 multipart/form-data MIME 类型来做到这一点。我应该说我正在使用 erlang 并且我计划收集从 返回的 http 数据包erlang:decode_packet/2,但我不想真正收集请求正文,直到 http 请求处理程序找到上传内容的位置。我是不是该

a) 继续收集尸体,忽略它非常大的可能性,因此可能由于内存不足而导致服务器崩溃?

b)在处理标头之前,不要在套接字上接收任何(可能不存在的)请求主体?

c) 做其他事情?

答案 c 的示例可能是:生成另一个进程来收集上传的内容并将其写入临时位置(以最大程度地减少内存使用),同时将该位置提供给 http 请求处理程序以供将来处理。但我只是不知道 - 这里有标准技术吗?

4

3 回答 3

2

在我看来,选项 b 显然是更好的选项。

在您不读取套接字的时间段内,TCP 代码将继续在内核中缓冲传入的数据。当它这样做时,它将向 HTTP 服务器通告越来越小的 TCP 窗口大小,直到最终(当内核中的 TCP 接收缓冲区已满时),TCP 窗口将关闭。

换句话说,通过不读取套接字,您允许 TCP 流控制完成它的工作。

于 2010-03-06T12:59:06.740 回答
0

在我的实现中,我将您的示例用于答案 c - 我从套接字块读取块并将块存储到临时文件。此外,afaik yaws 使用了类似的技术——你可以在 yaws/src/yaws_multipart.erl 看到它

于 2010-03-04T07:31:35.060 回答
0

存储到临时文件也是 PHP 做事的方式,所以这是一种久经考验的方式。您可以计算收到的字节数并在它达到没有意义的大小时断开连接。

于 2010-03-04T19:01:10.420 回答