HTTP响应的主体存储在哪里?(使用Rust + reqwest)

5
我最近在使用Rust中的reqwest包构建一个简单的CL下载管理器,以便研究HTTP协议。我已经基本了解了该协议的工作方式——下载文件时要查找哪些头信息,如何验证请求是否成功等等,但是我遇到了一个问题,就是不知道HTTP响应主体中实际的字节存储在哪里。
例如,使用reqwest发送请求并得到响应的过程非常快,因此我认为下载不可能在这个阶段进行。实际消耗时间的是从主体中读取字节。但是,这个主体肯定不能存储在RAM中,因为下载大文件会使内存使用量激增。我意识到,在不使用浏览器下载文件时,数据存储的位置可能因使用不同的HTTP框架而异。但我想要的更一般的解释是:当不使用浏览器下载大型HTTP响应主体时,它们存储在哪里?
1个回答

10
reqwest中,除非你要求它这样做(例如调用.bytes().json()),否则响应正文不会完全存储在内存中 - 此时网络连接仍然处于活动状态(标头已被完全接收,但不是正文),因此服务器负责存储或准备好提供其余响应。可能HTTP服务器在其内存中具有响应,也可能直接从自己的磁盘读取; 响应的某些部分将暂时存储在各种网络缓冲区中,或者沿着电缆从其网络移动到您的网络。
这就是为什么Response不实现Clone,并且检索正文的方法需要self的原因;除了读取响应标头之外,Response还是指向未完成的网络连接的句柄。您可以使用它来指示reqwest如何将文件的剩余部分交付给您 - 将其读入内存,将其解析为某些JSON或其他数据类型,甚至使用自己的代码处理字节进来。
每个良好的HTTP客户端都会具有此类功能,因为在执行下一步操作之前将大型响应完全存储在内存中是不高效的。

有点脱离原题,但这仍然无法解释为什么读取正文必须消耗整个响应self(包括头和状态码)。没有根本的理由说明在读取正文后无法获取请求头/状态码。当然,只能读取一次正文,但它可以借用需要读取正文的标头,而不是完全消耗它们。 - nirvana-msu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接