Files
cpp-httplib/docs-src/pages/ja/cookbook/c09-chunked-upload.md
2026-04-11 20:40:08 -04:00

2.1 KiB
Raw Permalink Blame History

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()を呼べば送信が完了します。

サイズがわかっている場合

送信するボディの合計サイズが事前にわかっているときは、ContentProvidersize_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するを参照してください。