Skip to documentation
SLOP

tiny.http.Request

Reference tiny.http Request

Defined in tiny.http.

API (17)

Actions

Public operations.

Types and contracts

Public types and contracts.

Fields and members

Public fields and members.

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

Source

Source: lib/http/src/message.zig:271

zig
pub const Request = struct {    method: Method,    path: []const u8,    version: Version,    headers: RequestHeaders,    body: ?[]const u8,    pub const Method = enum {        GET,        POST,        PUT,        DELETE,        HEAD,        OPTIONS,        PATCH,        CONNECT,        TRACE,    };    pub const Version = enum {        http_1_0,        http_1_1,    };    pub const QueryIterator = struct {        pub const Param = struct {            key: []const u8,            value: []const u8,        };        query: ?[]const u8,        pos: usize = 0,        pub fn next(self: *QueryIterator) ?Param {            const q = self.query orelse return null;            while (self.pos < q.len) {                const remaining = q[self.pos..];                const param_end = std.mem.indexOf(u8, remaining, "&") orelse remaining.len;                const param = remaining[0..param_end];                self.pos += param_end + 1;                if (param.len == 0) continue;                if (std.mem.indexOf(u8, param, "=")) |eq| {                    return .{                        .key = param[0..eq],                        .value = if (eq + 1 < param.len) param[eq + 1 ..] else "",                    };                } else {                    return .{ .key = param, .value = "" };                }            }            return null;        }        pub fn get(self: *QueryIterator, key: []const u8) ?[]const u8 {            var iter = QueryIterator{ .query = self.query, .pos = 0 };            while (iter.next()) |param| {                if (std.mem.eql(u8, param.key, key)) {                    return param.value;                }            }            return null;        }    };    pub fn parse(scratch: RequestScratch, data: []const u8) ParseError!RequestParseResult {        const survey = try surveyRequest(scratch, data);        var header_count: usize = 0;        var pos = survey.first_line_end + 2;        while (pos < survey.header_end) {            const line_end = std.mem.indexOf(u8, data[pos .. survey.header_end + 2], "\r\n") orelse {                unreachable;            };            const line = data[pos..][0..line_end];            const parsed = field.parseLine(line).?;            scratch.headers[header_count] = .{                .name = parsed.name,                .value = parsed.value,            };            header_count += 1;            pos += line_end + 2;        }        std.debug.assert(header_count == survey.header_count);        const body: ?[]const u8 = switch (survey.body) {            .none => null,            .borrowed => |borrowed| data[borrowed.start..][0..borrowed.length],            .chunked => |capacity| blk: {                const decoded = chunked.decodeSurveyedInto(                    scratch.body,                    data[survey.body_start..],                    capacity,                ) catch unreachable;                std.debug.assert(decoded.body.len == capacity.decoded_bytes);                std.debug.assert(decoded.consumed == capacity.consumed);                break :blk decoded.body;            },        };        return .{            .request = .{                .method = survey.method,                .path = survey.path,                .version = survey.version,                .headers = .{ .entries = scratch.headers[0..header_count] },                .body = body,            },            .consumed = survey.consumed,        };    }    fn parseMethod(s: []const u8) ?Method {        const methods = .{            .{ "GET", Method.GET },            .{ "POST", Method.POST },            .{ "PUT", Method.PUT },            .{ "DELETE", Method.DELETE },            .{ "HEAD", Method.HEAD },            .{ "OPTIONS", Method.OPTIONS },            .{ "PATCH", Method.PATCH },            .{ "CONNECT", Method.CONNECT },            .{ "TRACE", Method.TRACE },        };        inline for (methods) |pair| {            if (std.mem.eql(u8, s, pair[0])) return pair[1];        }        return null;    }    fn parseVersion(s: []const u8) ?Version {        if (std.mem.eql(u8, s, "HTTP/1.1")) return .http_1_1;        if (std.mem.eql(u8, s, "HTTP/1.0")) return .http_1_0;        return null;    }    fn findHeaderEnd(data: []const u8) ?usize {        if (data.len < 4) return null;        var i: usize = 0;        while (i + 3 < data.len) : (i += 1) {            if (data[i] == '\r' and data[i + 1] == '\n' and data[i + 2] == '\r' and data[i + 3] == '\n') {                return i;            }        }        return null;    }    pub fn isWebSocketUpgrade(self: *const Request) bool {        if (self.method != .GET or self.version != .http_1_1) return false;        const upgrade = self.headers.get("Upgrade") orelse return false;        const connection = self.headers.get("Connection") orelse return false;        return containsHeaderToken(upgrade, "websocket") and            containsHeaderToken(connection, "upgrade");    }    pub fn getWebSocketKey(self: *const Request) ?[]const u8 {        return self.headers.get("Sec-WebSocket-Key");    }    pub fn pathOnly(self: *const Request) []const u8 {        if (std.mem.indexOf(u8, self.path, "?")) |idx| {            return self.path[0..idx];        }        return self.path;    }    pub fn queryString(self: *const Request) ?[]const u8 {        if (std.mem.indexOf(u8, self.path, "?")) |idx| {            if (idx + 1 < self.path.len) {                return self.path[idx + 1 ..];            }        }        return null;    }    pub fn queryParams(self: *const Request) QueryIterator {        return QueryIterator{ .query = self.queryString() };    }};

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

zig
pub const Request = message.Request;
Called byCallsNo direct callersRequestHeadersgetRequestgetWebSocketKey
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersRequestHeadersgetprivate sourcelib.http.src.messagecontainsHeaderTokenRequestisWebSocketUpgrade
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.http.src.message.TestParsedRequestinittest sourcelib.http.src.message.test_Requestparse: chunked body capacity is check...test sourcelib.http.src.messagetest: Request capacity failures prese...test sourcelib.http.src.messagetest: Request content-length body bor...test sourcelib.http.src.messagetest: Request parser accepts exact li...+6 moreprivate sourcelib.http.src.messagesurveyRequestRequestparse
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callersRequestqueryStringRequestqueryParams
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsRequestqueryParamsRequestqueryString
Static calls · unresolved targets: 0 · external targets: 0.

Complete caller list for Request.parse

11 direct callers.

Audit

Definitions13
Public names13
Members20
Version26.7.0
Revisiondaab053ee433