mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-12 19:58:29 +00:00
2.1 KiB
2.1 KiB
title, order, status
| title | order | status |
|---|---|---|
| C09. チャンク転送でボディを送る | 9 | draft |
送信するボディのサイズが事前にわからないとき、たとえばリアルタイムに生成されるデータや別のストリームから流し込むデータを送りたいときは、ContentProviderWithoutLengthを使います。HTTPのチャンク転送エンコーディング(chunked transfer-encoding)として送信されます。
基本の使い方
httplib::Client cli("http://localhost:8080");
auto res = cli.Post("/stream",
[&](size_t offset, httplib::DataSink &sink) {
std::string chunk = produce_next_chunk();
if (chunk.empty()) {
sink.done(); // 送信終了
return true;
}
return sink.write(chunk.data(), chunk.size());
},
"application/octet-stream");
ラムダは「次のチャンクを作ってsink.write()で送る」だけです。データがもう無くなったらsink.done()を呼べば送信が完了します。
サイズがわかっている場合
送信するボディの合計サイズが事前にわかっているときは、ContentProvider(size_t offset, size_t length, DataSink &sinkを取るタイプ)と合計サイズを渡す別のオーバーロードを使います。
size_t total_size = get_total_size();
auto res = cli.Post("/upload", total_size,
[&](size_t offset, size_t length, httplib::DataSink &sink) {
auto data = read_range(offset, length);
return sink.write(data.data(), data.size());
},
"application/octet-stream");
サイズがわかっているとContent-Lengthヘッダーが付くので、サーバー側で進捗を把握しやすくなります。可能ならこちらを使いましょう。
Detail:
sink.write()は書き込みが成功したかどうかをboolで返します。falseが返ったら回線が切れています。ラムダはそのままfalseを返して終了しましょう。
ファイルをそのまま送るだけなら、
make_file_body()が便利です。C08. ファイルを生バイナリとしてPOSTするを参照してください。