Skip to documentation
SLOP

tiny.http.Response

Reference tiny.http Response

Defined in tiny.http.

API (13)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callstiny.httpResponse
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/http/src/response.zig:275

zig
pub const Response = struct {    status: u16,    status_text: []const u8,    headers: Headers,    body: ?[]const u8,    body_release: ?BodyRelease,    head_storage: []u8,    const BodyRelease = struct {        context: *anyopaque,        callback: *const fn (*anyopaque, []const u8) void,        body: []const u8,    };    pub fn init(scratch: Scratch) Response {        return .{            .status = 200,            .status_text = "OK",            .headers = .{ .entries = scratch.headers, .length = 0 },            .body = null,            .body_release = null,            .head_storage = scratch.head,        };    }    pub fn deinit(self: *Response) void {        if (self.body_release) |release| {            release.callback(release.context, release.body);        }        self.body = null;        self.body_release = null;    }    pub fn setBodyWithRelease(        self: *Response,        body: []const u8,        context: anytype,        comptime release_body: anytype,    ) void {        const Context = @TypeOf(context);        const info = @typeInfo(Context);        if (info != .pointer or info.pointer.size != .one) {            @compileError("response body release context must be a single-item pointer");        }        const Erased = struct {            fn release(erased: *anyopaque, bytes: []const u8) void {                const typed: Context = @ptrCast(@alignCast(erased));                release_body(typed, bytes);            }        };        self.deinit();        self.body = body;        self.body_release = .{            .context = @ptrCast(@constCast(context)),            .callback = Erased.release,            .body = body,        };    }    pub fn setHeader(self: *Response, name: []const u8, value: []const u8) Error!void {        try self.headers.set(name, value);    }    pub fn serialize(self: *const Response) Error!Serialized {        return self.serializeWithOptions(.{});    }    pub fn serializeForMethod(self: *const Response, method: Request.Method) Error!Serialized {        return self.serializeWithOptions(.{ .method = method });    }    pub fn switchingProtocols(scratch: Scratch, accept_key: []const u8) Error!Response {        if (scratch.headers.len < 3) return error.HeaderCapacityExceeded;        var response = Response.init(scratch);        response.status = 101;        response.status_text = "Switching Protocols";        try response.setHeader("Upgrade", "websocket");        try response.setHeader("Connection", "Upgrade");        try response.setHeader("Sec-WebSocket-Accept", accept_key);        return response;    }    fn serializeWithOptions(self: *const Response, options: SerializeOptions) Error!Serialized {        const head_length = try self.serializedHeadLength();        if (head_length > self.head_storage.len) return error.HeadCapacityExceeded;        var fixed = std.Io.Writer.fixed(self.head_storage[0..head_length]);        const writer = &fixed;        writer.print("HTTP/1.1 {d} {s}\r\n", .{ self.status, self.status_text }) catch unreachable;        for (self.headers.entries[0..self.headers.length]) |entry| {            if (!self.shouldWriteHeader(entry.name)) continue;            writer.print("{s}: {s}\r\n", .{ entry.name, entry.value }) catch unreachable;        }        if (self.body) |body| {            if (self.shouldWriteContentLength() and !self.headers.contains("Content-Length")) {                writer.print("Content-Length: {d}\r\n", .{body.len}) catch unreachable;            }        }        writer.writeAll("\r\n") catch unreachable;        std.debug.assert(writer.buffered().len == head_length);        return .{            .head = writer.buffered(),            .body = if (self.shouldWriteBody(options)) self.body else null,        };    }    fn serializedHeadLength(self: *const Response) Error!usize {        var length: usize = 0;        length = try addLength(length, "HTTP/1.1 ".len);        length = try addLength(length, decimalLength(self.status));        length = try addLength(length, " ".len);        length = try addLength(length, self.status_text.len);        length = try addLength(length, "\r\n".len);        for (self.headers.entries[0..self.headers.length]) |entry| {            if (!self.shouldWriteHeader(entry.name)) continue;            length = try addLength(length, entry.name.len);            length = try addLength(length, ": ".len);            length = try addLength(length, entry.value.len);            length = try addLength(length, "\r\n".len);        }        if (self.body) |body| {            if (self.shouldWriteContentLength() and !self.headers.contains("Content-Length")) {                length = try addLength(length, "Content-Length: ".len);                length = try addLength(length, decimalLength(body.len));                length = try addLength(length, "\r\n".len);            }        }        return addLength(length, "\r\n".len);    }    fn shouldWriteHeader(self: *const Response, name: []const u8) bool {        if (std.ascii.eqlIgnoreCase(name, "Transfer-Encoding")) {            return self.statusAllowsBody();        }        if (std.ascii.eqlIgnoreCase(name, "Content-Length")) {            return self.statusAllowsContentLength();        }        return true;    }    fn shouldWriteContentLength(self: *const Response) bool {        return self.statusAllowsContentLength();    }    fn shouldWriteBody(self: *const Response, options: SerializeOptions) bool {        if (self.body == null) return false;        if (!self.statusAllowsBody()) return false;        if (options.method) |method| {            if (method == .HEAD) return false;        }        return true;    }    fn statusAllowsBody(self: *const Response) bool {        if (self.status >= 100 and self.status < 200) return false;        return self.status != 204 and self.status != 304;    }    fn statusAllowsContentLength(self: *const Response) bool {        if (self.status >= 100 and self.status < 200) return false;        return self.status != 204;    }};

Source: lib/http/src/root.zig:48

zig
pub const Response = response.Response;
Called byCallsNo direct callsResponsesetBodyWithReleaseprivate sourcelib.http.src.response.TestResponsedeinittiny.httpRouterResponsedeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsResponseswitchingProtocolsprivate sourcelib.http.src.response.TestResponseinittest sourcelib.http.src.responsetest: Response capacity failures pres...test sourcelib.http.src.responsetest: Response serialization accepts ...test sourcelib.http.src.responsetest: Response serialization remains ...tiny.httpRouterResponseinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.http.src.responsetest: Response capacity failures pres...test sourcelib.http.src.responsetest: Response serialization accepts ...test sourcelib.http.src.responsetest: Response serialization remains ...tiny.httpRouterprivate sourcelib.http.src.response.ResponseserializeWithOptionsResponseserialize
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstiny.httpRouterprivate sourcelib.http.src.response.ResponseserializeWithOptionsResponseserializeForMethod
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersResponsedeinitResponsesetBodyWithRelease
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsResponseswitchingProtocolstest sourcelib.http.src.responsetest: Response capacity failures pres...test sourcelib.http.src.responsetest: Response serialization remains ...private sourcelib.http.src.response.HeaderssetResponsesetHeader
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.http.src.responsetest: Response capacity failures pres...test sourcelib.http.src.responsetest: Response switchingProtocols pop...tiny.httpRoutertiny.httpupgradeWebsocketResponseinitResponsesetHeaderResponseswitchingProtocols
Static calls · unresolved targets: 0 · external targets: 0.

Audit

Definitions8
Public names8
Members6
Version26.7.0
Revisiondaab053ee433