所以,假设我正在编写一个Web服务器,我想支持“非常大”的文件上传。让我们进一步假设我的意思是通过标准的multipart / form-data MIME类型来实现这一点。我应该说我正在使用erlang并且我计划在从erlang:decode_packet/2
返回时收集http数据包,但我不想实际收集请求正文,直到http请求处理程序找到上传的位置要去的内容。我应该
a)反过来收集身体,忽略了它非常大的可能性,因此可能因内存不足而导致服务器崩溃?
b)在处理完标题之前,不要在套接字上接收任何(可能不存在的)请求体?
c)做别的事吗?答案c的示例可能是:生成另一个进程以收集上载的内容并将其写入临时位置(以便最小化内存使用),同时将该位置提供给http请求处理程序以供将来处理。但我只是不知道 - 这里有标准技术吗?
答案 0 :(得分:2)
在我看来,选项b显然是优越的选项。
在您不读取套接字的过程中,TCP代码将继续缓冲内核中的传入数据。当它这样做时,它会向HTTP服务器通告一个越来越小的TCP窗口大小,直到最终(当内核中的TCP接收缓冲区已满)时,TCP窗口将关闭。
换句话说,通过不读取套接字,您可以让TCP流控制完成它的工作。
答案 1 :(得分:0)
在我的实现中,我使用你的例子来回答c - 我通过chunk读取socket chunk并将块存储到临时文件。此外,afaik yaws使用simillar技术 - 你可以在yaws / src / yaws_multipart.erl上看到它
答案 2 :(得分:0)
存储到临时文件也是PHP做事的方式,因此它是一种经过试验和测试的方式。您可以计算接收到的字节数,如果达到无意义的大小则断开连接。