You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于http::response的prepare_payload()移除Transfer-Encoding: chunked的疑问及分块响应的方法调用建议

关于http::response的prepare_payload()移除Transfer-Encoding: chunked的疑问及分块响应的方法调用建议

嘿,我来帮你把这个问题掰扯明白~

先看你的代码示例:

http::response<http::string_body> res;
res.version(11);
res.result(http::status::ok);
res.set(http::field::server, "Example-Server");
res.body() = "test";
// Chunked transfer encoding
res.chunked(true);
std::cout << res;
res.prepare_payload();
std::cout << res;

为什么prepare_payload()会替换Transfer-Encoding: chunked

这个方法的核心作用就是自动保证响应头部和负载的一致性,同时优化传输方式。当你设置了chunked(true),但此时你的响应body是长度明确的固定字符串(比如这里的"test",长度为4),Boost.Beast会判断:既然body长度已知,使用Content-Length头部的普通传输比分块传输更高效(分块会额外增加分块标记的开销),所以它会自动关闭分块模式,替换成Content-Length头部。这是库内置的优化逻辑,完全符合HTTP协议规范——两种方式都能正确传输,但已知长度时Content-Length的效率更高。

分块响应应该调用prepare_payload()吗?

这得看你的具体场景:

  • 如果body长度无法提前确定(比如实时生成的流式数据、动态日志输出):分块传输就是最佳选择,这时候你绝对不要调用prepare_payload()。因为这个方法会尝试计算body长度,一旦它能算出明确长度,就会自动关闭分块模式,违背你的初衷。这种情况下,你需要手动处理分块的序列化和发送(比如使用http::serializer来逐块输出内容)。
  • 如果body长度已知:哪怕你一开始误设置了chunked(true)prepare_payload()也会帮你转换成更高效的Content-Length模式,这时候调用它是合理的。但如果你确实需要强制使用分块传输(比如某些特定业务要求),那你就不能调用这个方法,并且要自己维护好分块的格式(比如手动添加分块大小和结束标记)。

回到你的场景:
你设置的body是固定的"test",长度明确,所以prepare_payload()自动做了优化切换。如果就是想保留分块传输,直接去掉res.prepare_payload();这行代码就行——你之前打印的未调用方法的输出已经是正确的分块格式了。

内容来源于stack exchange

火山引擎 最新活动