Streaming¶
Contents | Previous: Authentication, TLS, and Proxy | Next: Client and Request Lifecycle
View in another language — C++ · C#/.NET · Java · Kotlin · Node/TypeScript
After reading this chapter
This chapter processes a response in chunks and sends a request body in parts. Its code comes from each language's HttpClient tutorial.
Streaming moves a large body through a caller callback or provider. Unlike a JSON body, it does not serialize or accumulate the whole body. Response Rules covers status and compression rules.
The provider and sink are each consumed once while the body moves. This is why the streaming path does not apply replay or transparent decompression.
1. Response Chunks Flow Through a Download Sink¶
A download sink is a callback invoked for each received body chunk. A raw response carries status, headers, and the body before JSON decoding. The final raw response from a download preserves status and headers; bodies from intermediate redirect responses do not reach the sink.
var downloadChunks = 0;
var downloadBytes = 0;
var downloaded = await client
.Get($"/rooms/{room.Body}/export")
.DownloadAsync(chunk =>
{
downloadChunks++;
downloadBytes += chunk.Length;
});
Console.WriteLine($"download stream: chunks {downloadChunks} bytes {downloadBytes}");
The example counts each export-body chunk and accumulates the total number of chunks and bytes.
2. Request Chunks Come from a Body Stream Provider¶
A body stream provider returns the next chunk to send and signals completion with the language's empty value. Its configuration includes the content type.
var uploadChunks = new Queue<byte[]>(
new[]
{
Encoding.UTF8.GetBytes("{\"playerId\":\"p2\",\"text\":\"one\"}\n"),
Encoding.UTF8.GetBytes("{\"playerId\":\"p2\",\"text\":\"two\"}\n"),
Encoding.UTF8.GetBytes("{\"playerId\":\"p2\",\"text\":\"three\"}\n"),
}
);
var imported = await client
.Post($"/rooms/{room.Body}/import")
.BodyStream(
() => uploadChunks.Count > 0 ? uploadChunks.Dequeue() : null,
"application/x-ndjson"
)
.Async<ImportResponse>();
Console.WriteLine($"upload stream: imported {imported.Body.Imported}");
The example supplies three NDJSON lines in sequence and confirms that the server imported three items.
3. Retry and Decompression Are Excluded¶
A download sink and a body stream provider consume their body once and cannot recreate it. A streaming request is therefore excluded from retry and redirect replay. A download sink receives compressed response bytes unchanged; decompression is not applied.
4. Next Chapter¶
Client and Request Lifecycle covers client reuse, close timing, response completion, and timeout boundaries.