tiny.http.Request
Defined in tiny.http.
API (17)
Actions
Public operations.
QueryIterator.getQueryIterator.nextgetWebSocketKeyisWebSocketUpgradeparsepathOnlyqueryParamsqueryString
Types and contracts
Public types and contracts.
Fields and members
Public fields and members.
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;Complete caller list for Request.parse
11 direct callers.
lib.http.src.message.TestParsedRequest.init[function] — private source atlib/http/src/message.zig:578in nearest public ownerlib.http.src.messagelib.http.src.message.test_Request.parse:_chunked_body_capacity_is_checked_before_mutation[function] — test source atlib/http/src/message.zig:1012in nearest public ownerlib.http.src.messagelib.http.src.message.test_Request_capacity_failures_preserve_header_and_body_storage[function] — test source atlib/http/src/message.zig:753in nearest public ownerlib.http.src.messagelib.http.src.message.test_Request_content-length_body_borrows_input_and_preserves_decoded_storage[function] — test source atlib/http/src/message.zig:847in nearest public ownerlib.http.src.messagelib.http.src.message.test_Request_parser_accepts_exact_limits_and_rejects_max_plus_one[function] — test source atlib/http/src/message.zig:801in nearest public ownerlib.http.src.messagelib.http.src.message.test_Request_parsing_remains_allocation-free_after_storage_seals[function] — test source atlib/http/src/message.zig:867in nearest public ownerlib.http.src.messagelib.http.src.properties.message.RobustnessProperty.property[function] — private source atlib/http/src/properties/message.zig:176in nearest public ownerlib.http.src.properties.messagelib.http.src.properties.message.RoundTripProperty.property[function] — private source atlib/http/src/properties/message.zig:148in nearest public ownerlib.http.src.properties.messagetiny.http.Router[function] atlib/http/src/router/runtime.zig:39lib.http.src.router.test.test_upgradeWebsocket_acquires_bounded_storage_before_the_switching_response[function] — test source atlib/http/src/router/test.zig:463in nearest public ownerlib.http.src.router.testlib.http.src.websocket.TestParsedRequest.init[function] — private source atlib/http/src/websocket.zig:1352in nearest public ownerlib.http.src.websocket
Audit
| Definitions | 13 |
|---|---|
| Public names | 13 |
| Members | 20 |
| Version | 26.7.0 |
| Revision | daab053ee433 |