mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 23:24:09 +00:00
feat: make example for parseAccept
This commit is contained in:
parent
698c06d808
commit
6d646b62d6
2 changed files with 71 additions and 38 deletions
|
@ -70,6 +70,7 @@ pub fn build(b: *std.Build) !void {
|
||||||
.{ .name = "middleware_with_endpoint", .src = "examples/middleware_with_endpoint/middleware_with_endpoint.zig" },
|
.{ .name = "middleware_with_endpoint", .src = "examples/middleware_with_endpoint/middleware_with_endpoint.zig" },
|
||||||
.{ .name = "senderror", .src = "examples/senderror/senderror.zig" },
|
.{ .name = "senderror", .src = "examples/senderror/senderror.zig" },
|
||||||
.{ .name = "bindataformpost", .src = "examples/bindataformpost/bindataformpost.zig" },
|
.{ .name = "bindataformpost", .src = "examples/bindataformpost/bindataformpost.zig" },
|
||||||
|
.{ .name = "accept", .src = "examples/accept/accept.zig" },
|
||||||
}) |excfg| {
|
}) |excfg| {
|
||||||
const ex_name = excfg.name;
|
const ex_name = excfg.name;
|
||||||
const ex_src = excfg.src;
|
const ex_src = excfg.src;
|
||||||
|
|
108
src/request.zig
108
src/request.zig
|
@ -6,6 +6,8 @@ const fio = @import("fio.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
const zap = @import("zap.zig");
|
const zap = @import("zap.zig");
|
||||||
|
|
||||||
|
const ContentType = zap.ContentType;
|
||||||
|
|
||||||
pub const HttpError = error{
|
pub const HttpError = error{
|
||||||
HttpSendBody,
|
HttpSendBody,
|
||||||
HttpSetContentType,
|
HttpSetContentType,
|
||||||
|
@ -16,15 +18,6 @@ pub const HttpError = error{
|
||||||
SendFile,
|
SendFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Http Content Type enum.
|
|
||||||
/// Needs some love.
|
|
||||||
pub const ContentType = enum {
|
|
||||||
TEXT,
|
|
||||||
HTML,
|
|
||||||
JSON,
|
|
||||||
// TODO: more content types
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Key value pair of strings from HTTP parameters
|
/// Key value pair of strings from HTTP parameters
|
||||||
pub const HttpParamStrKV = struct {
|
pub const HttpParamStrKV = struct {
|
||||||
key: util.FreeOrNot,
|
key: util.FreeOrNot,
|
||||||
|
@ -585,39 +578,77 @@ pub fn parseCookies(self: *const Self, url_encoded: bool) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const MIMEType = struct {
|
pub const MIMEType = struct {
|
||||||
type: union(enum) {
|
type: Fragment,
|
||||||
|
subtype: Fragment,
|
||||||
|
|
||||||
|
const Fragment = union(enum) {
|
||||||
glob,
|
glob,
|
||||||
value: []const u8,
|
value: []const u8,
|
||||||
type: Type,
|
|
||||||
},
|
|
||||||
subtype: union(enum) {
|
|
||||||
glob,
|
|
||||||
value: []const u8,
|
|
||||||
},
|
|
||||||
const Type = enum {
|
|
||||||
application,
|
|
||||||
audio,
|
|
||||||
font,
|
|
||||||
example,
|
|
||||||
image,
|
|
||||||
message,
|
|
||||||
model,
|
|
||||||
multipart,
|
|
||||||
text,
|
|
||||||
video,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const AcceptItem = struct {
|
pub const AcceptItem = struct {
|
||||||
mimetype: MIMEType,
|
mimetype: MIMEType,
|
||||||
q: f64,
|
q: f64,
|
||||||
|
|
||||||
|
pub fn lessThan(_: void, lhs: AcceptItem, rhs: AcceptItem) bool {
|
||||||
|
return lhs.q < rhs.q;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn asCommon(item: AcceptItem) ?Common {
|
||||||
|
if (item.mimetype.type == .glob) {
|
||||||
|
if (item.mimetype.subtype == .glob) return .@"*/*";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (std.mem.eql(u8, "text", item.mimetype.type.value)) {
|
||||||
|
if (item.mimetype.subtype == .glob) {
|
||||||
|
return .@"text/*";
|
||||||
|
} else if (std.mem.eql(u8, "html", item.mimetype.subtype.value)) {
|
||||||
|
return .@"text/html";
|
||||||
|
} else if (std.mem.eql(u8, "plain", item.mimetype.subtype.value)) {
|
||||||
|
return .@"text/plain";
|
||||||
|
}
|
||||||
|
} else if (std.mem.eql(u8, "application", item.mimetype.type.value)) {
|
||||||
|
if (item.mimetype.subtype == .glob) {
|
||||||
|
return .@"application/*";
|
||||||
|
} else if (std.mem.eql(u8, "xml", item.mimetype.subtype.value)) {
|
||||||
|
return .@"application/xml";
|
||||||
|
} else if (std.mem.eql(u8, "json", item.mimetype.subtype.value)) {
|
||||||
|
return .@"application/json";
|
||||||
|
} else if (std.mem.eql(u8, "xhtml+xml", item.mimetype.subtype.value)) {
|
||||||
|
return .@"application/xhtml+xml";
|
||||||
|
}
|
||||||
|
} else if (std.mem.eql(u8, "image", item.mimetype.type.value)) {
|
||||||
|
if (item.mimetype.subtype == .glob) {
|
||||||
|
return .@"image/*";
|
||||||
|
} else if (std.mem.eql(u8, "avif", item.mimetype.subtype.value)) {
|
||||||
|
return .@"image/avif";
|
||||||
|
} else if (std.mem.eql(u8, "webp", item.mimetype.subtype.value)) {
|
||||||
|
return .@"image/webp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Common = enum {
|
||||||
|
@"*/*",
|
||||||
|
@"text/*",
|
||||||
|
@"text/html",
|
||||||
|
@"text/plain",
|
||||||
|
@"application/*",
|
||||||
|
@"application/xhtml+xml",
|
||||||
|
@"application/xml",
|
||||||
|
@"application/json",
|
||||||
|
@"image/*",
|
||||||
|
@"image/avif",
|
||||||
|
@"image/webp",
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns an unsorted list of `AcceptItem`s
|
/// Parses `Accept:` http header into `list`.
|
||||||
pub fn parseAcceptAlloc(self: *const Self, allocator: std.mem.Allocator) !std.ArrayList(AcceptItem) {
|
pub fn parseAccept(self: *const Self, list: *std.ArrayList(AcceptItem)) !void {
|
||||||
const accept_str = self.getHeaderCommon(.accept);
|
const accept_str = self.getHeaderCommon(.accept) orelse return error.NoAccept;
|
||||||
|
|
||||||
var list = std.ArrayList(AcceptItem).init(allocator);
|
|
||||||
|
|
||||||
var tok_iter = std.mem.tokenize(u8, accept_str, ", ");
|
var tok_iter = std.mem.tokenize(u8, accept_str, ", ");
|
||||||
while (tok_iter.next()) |tok| {
|
while (tok_iter.next()) |tok| {
|
||||||
|
@ -633,19 +664,17 @@ pub fn parseAcceptAlloc(self: *const Self, allocator: std.mem.Allocator) !std.Ar
|
||||||
break :q_factor parsed;
|
break :q_factor parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
var type_split_iter = std.mem.split(u8, mimetype_str, '/');
|
var type_split_iter = std.mem.split(u8, mimetype_str, "/");
|
||||||
|
|
||||||
const mimetype_type_str = type_split_iter.next() orelse continue;
|
const mimetype_type_str = type_split_iter.next() orelse continue;
|
||||||
const mimetype_subtype_str = type_split_iter.next() orelse continue;
|
const mimetype_subtype_str = type_split_iter.next() orelse continue;
|
||||||
|
|
||||||
const mimetype_type = if (std.mem.eql(u8, "*", mimetype_type_str))
|
const mimetype_type: MIMEType.Fragment = if (std.mem.eql(u8, "*", mimetype_type_str))
|
||||||
.glob
|
.glob
|
||||||
else if (std.meta.stringToEnum(MIMEType.Type, mimetype_type_str)) |t|
|
|
||||||
.{ .type = t }
|
|
||||||
else
|
else
|
||||||
.{ .value = mimetype_type_str };
|
.{ .value = mimetype_type_str };
|
||||||
|
|
||||||
const mimetype_subtype = if (std.mem.eql(u8, "*", mimetype_subtype_str))
|
const mimetype_subtype: MIMEType.Fragment = if (std.mem.eql(u8, "*", mimetype_subtype_str))
|
||||||
.glob
|
.glob
|
||||||
else
|
else
|
||||||
.{ .value = mimetype_subtype_str };
|
.{ .value = mimetype_subtype_str };
|
||||||
|
@ -658,8 +687,11 @@ pub fn parseAcceptAlloc(self: *const Self, allocator: std.mem.Allocator) !std.Ar
|
||||||
.q = q_factor,
|
.q = q_factor,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
/// Sorts list from `parseAccept`
|
||||||
|
pub fn sortAccept(accept_list: []AcceptItem) void {
|
||||||
|
std.sort.insertion(AcceptItem, accept_list, {}, AcceptItem.lessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a response cookie
|
/// Set a response cookie
|
||||||
|
|
Loading…
Add table
Reference in a new issue