--- title: "C10. Receive a Response as a Stream" order: 10 status: "draft" --- To receive a response body chunk by chunk, use a `ContentReceiver`. It's the obvious choice for large files, but it's equally handy for NDJSON (newline-delimited JSON) or log streams where you want to start processing data as it arrives. ## Process each chunk ```cpp httplib::Client cli("http://localhost:8080"); auto res = cli.Get("/logs/stream", [](const char *data, size_t len) { std::cout.write(data, len); std::cout.flush(); return true; // return false to stop receiving }); ``` Data arrives in the lambda in the order it's received from the server. Return `false` from the callback to stop the download partway through. ## Parse NDJSON line by line Here's a buffered approach for processing newline-delimited JSON one line at a time. ```cpp std::string buffer; auto res = cli.Get("/events", [&](const char *data, size_t len) { buffer.append(data, len); size_t pos; while ((pos = buffer.find('\n')) != std::string::npos) { auto line = buffer.substr(0, pos); buffer.erase(0, pos + 1); if (!line.empty()) { auto j = nlohmann::json::parse(line); handle_event(j); } } return true; }); ``` Accumulate into a buffer, then pull out and parse one line each time you see a newline. This is the standard pattern for consuming a streaming API in real time. > **Warning:** When you pass a `ContentReceiver`, `res->body` stays **empty**. Store or process the body inside the callback yourself. > To track download progress, combine this with C11. Use the Progress Callback. > For Server-Sent Events (SSE), see E04. Receive SSE on the Client.