Function respondStreaming [src]

The header is buffered but not sent until Response.flush 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 a flag on the returned Response 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 send_buffer is large enough to store the entire response header. Asserts status is not continue.

Prototype

pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) Response

Parameters

request: *Requestoptions: RespondStreamingOptions

Source

pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) Response { 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 ""; var h = std.ArrayListUnmanaged(u8).initBuffer(options.send_buffer); const elide_body = if (request.head.expect != null) eb: { // reader() and hence discardBody() above sets expect to null if it // is handled. So the fact that it is not null here means unhandled. h.appendSliceAssumeCapacity("HTTP/1.1 417 Expectation Failed\r\n"); if (!keep_alive) h.appendSliceAssumeCapacity("connection: close\r\n"); h.appendSliceAssumeCapacity("content-length: 0\r\n\r\n"); break :eb true; } else eb: { h.fixedWriter().print("{s} {d} {s}\r\n", .{ @tagName(o.version), @intFromEnum(o.status), phrase, }) catch unreachable; switch (o.version) { .@"HTTP/1.0" => if (keep_alive) h.appendSliceAssumeCapacity("connection: keep-alive\r\n"), .@"HTTP/1.1" => if (!keep_alive) h.appendSliceAssumeCapacity("connection: close\r\n"), } if (o.transfer_encoding) |transfer_encoding| switch (transfer_encoding) { .chunked => h.appendSliceAssumeCapacity("transfer-encoding: chunked\r\n"), .none => {}, } else if (options.content_length) |len| { h.fixedWriter().print("content-length: {d}\r\n", .{len}) catch unreachable; } else { h.appendSliceAssumeCapacity("transfer-encoding: chunked\r\n"); } for (o.extra_headers) |header| { assert(header.name.len != 0); h.appendSliceAssumeCapacity(header.name); h.appendSliceAssumeCapacity(": "); h.appendSliceAssumeCapacity(header.value); h.appendSliceAssumeCapacity("\r\n"); } h.appendSliceAssumeCapacity("\r\n"); break :eb request.head.method == .HEAD; }; return .{ .stream = request.server.connection.stream, .send_buffer = options.send_buffer, .send_buffer_start = 0, .send_buffer_end = h.items.len, .transfer_encoding = if (o.transfer_encoding) |te| switch (te) { .chunked => .chunked, .none => .none, } else if (options.content_length) |len| .{ .content_length = len, } else .chunked, .elide_body = elide_body, .chunk_len = 0, }; }