respondStreaming
The header is not guaranteed to be sent until BodyWriter.flush or
BodyWriter.end is called.
If the request contains a body and the connection is to be reused,
discards the request body, leaving the Server in the ready state. If
this discarding fails, the connection is marked as not to be reused and
no error is surfaced.
HEAD requests are handled transparently by setting the
BodyWriter.elide flag on the returned BodyWriter, causing
the response stream to omit the body. However, it may be worth noticing
that flag and skipping any expensive work that would otherwise need to
be done to satisfy the request.
Asserts status is not continue.
Function parameters
Parameters
- request:*Request
- buffer:[]u8
Type definitions in this namespace
Types
Initialize an HTTP server that can respond to multiple requests on the same
Functions
- init
- Initialize an HTTP server that can respond to multiple requests on the same
Error sets in this namespace
Error Sets
Source
Implementation
pub fn respondStreaming(
request: *Request,
buffer: []u8,
options: RespondStreamingOptions,
) ExpectContinueError!http.BodyWriter {
try writeExpectContinue(request);
const o = options.respond_options;
assert(o.status != .@"continue");
const transfer_encoding_none = (o.transfer_encoding orelse .chunked) == .none;
const server_keep_alive = !transfer_encoding_none and o.keep_alive;
const keep_alive = request.discardBody(server_keep_alive);
const phrase = o.reason orelse o.status.phrase() orelse "";
const out = request.server.out;
try out.print("{s} {d} {s}\r\n", .{
@tagName(o.version), @intFromEnum(o.status), phrase,
});
switch (o.version) {
.@"HTTP/1.0" => if (keep_alive) try out.writeAll("connection: keep-alive\r\n"),
.@"HTTP/1.1" => if (!keep_alive) try out.writeAll("connection: close\r\n"),
}
if (o.transfer_encoding) |transfer_encoding| switch (transfer_encoding) {
.chunked => try out.writeAll("transfer-encoding: chunked\r\n"),
.none => {},
} else if (options.content_length) |len| {
try out.print("content-length: {d}\r\n", .{len});
} else {
try out.writeAll("transfer-encoding: chunked\r\n");
}
for (o.extra_headers) |header| {
assert(header.name.len != 0);
var bufs: [4][]const u8 = .{ header.name, ": ", header.value, "\r\n" };
try out.writeVecAll(&bufs);
}
try out.writeAll("\r\n");
const elide_body = request.head.method == .HEAD;
const state: http.BodyWriter.State = if (o.transfer_encoding) |te| switch (te) {
.chunked => .init_chunked,
.none => .none,
} else if (options.content_length) |len| .{
.content_length = len,
} else .init_chunked;
return if (elide_body) .{
.http_protocol_output = request.server.out,
.state = state,
.writer = .{
.buffer = buffer,
.vtable = &.{
.drain = http.BodyWriter.elidingDrain,
.sendFile = http.BodyWriter.elidingSendFile,
},
},
} else .{
.http_protocol_output = request.server.out,
.state = state,
.writer = .{
.buffer = buffer,
.vtable = switch (state) {
.none => &.{
.drain = http.BodyWriter.noneDrain,
.sendFile = http.BodyWriter.noneSendFile,
},
.content_length => &.{
.drain = http.BodyWriter.contentLengthDrain,
.sendFile = http.BodyWriter.contentLengthSendFile,
},
.chunk_len => &.{
.drain = http.BodyWriter.chunkedDrain,
.sendFile = http.BodyWriter.chunkedSendFile,
},
.end => unreachable,
},
},
};
}