web: some stuff
This commit is contained in:
338
packages/web/src/http/Header.zig
Normal file
338
packages/web/src/http/Header.zig
Normal file
@@ -0,0 +1,338 @@
|
||||
const std = @import("std");
|
||||
const Header = @This();
|
||||
|
||||
name: Name,
|
||||
value: []const u8,
|
||||
|
||||
pub fn init(name: []const u8, value: []const u8) Header {
|
||||
return .{
|
||||
.name = .init(name),
|
||||
.value = value,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initKnown(known: Name.Known, value: []const u8) Header {
|
||||
return .{
|
||||
.name = .initKnown(known),
|
||||
.value = value,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isKnown(self: Header, known: Name.Known) bool {
|
||||
return switch (self.name) {
|
||||
.known => |x| x == known,
|
||||
.other => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Name = union(enum) {
|
||||
known: Known,
|
||||
other: []const u8,
|
||||
|
||||
pub fn initKnown(known: Known) Name {
|
||||
return .{ .known = known };
|
||||
}
|
||||
|
||||
pub fn initOther(other: []const u8) Name {
|
||||
return .{ .other = other };
|
||||
}
|
||||
|
||||
pub fn init(name: []const u8) Name {
|
||||
return if (Known.isKnown(name)) |known| .initKnown(known) else .initOther(name);
|
||||
}
|
||||
|
||||
pub const Known = enum {
|
||||
@"A-IM",
|
||||
Accept,
|
||||
@"Accept-Additions",
|
||||
@"Accept-CH",
|
||||
@"Accept-Charset",
|
||||
@"Accept-Datetime",
|
||||
@"Accept-Encoding",
|
||||
@"Accept-Features",
|
||||
@"Accept-Language",
|
||||
@"Accept-Patch",
|
||||
@"Accept-Post",
|
||||
@"Accept-Query",
|
||||
@"Accept-Ranges",
|
||||
@"Accept-Signature",
|
||||
@"Access-Control",
|
||||
@"Access-Control-Allow-Credentials",
|
||||
@"Access-Control-Allow-Headers",
|
||||
@"Access-Control-Allow-Methods",
|
||||
@"Access-Control-Allow-Origin",
|
||||
@"Access-Control-Expose-Headers",
|
||||
@"Access-Control-Max-Age",
|
||||
@"Access-Control-Request-Headers",
|
||||
@"Access-Control-Request-Method",
|
||||
@"Activate-Storage-Access",
|
||||
Age,
|
||||
Allow,
|
||||
ALPN,
|
||||
@"Alt-Svc",
|
||||
@"Alt-Used",
|
||||
Alternates,
|
||||
@"AMP-Cache-Transform",
|
||||
@"Apply-To-Redirect-Ref",
|
||||
@"Authentication-Control",
|
||||
@"Authentication-Info",
|
||||
Authorization,
|
||||
@"Available-Dictionary",
|
||||
@"C-Ext",
|
||||
@"C-Man",
|
||||
@"C-Opt",
|
||||
@"C-PEP",
|
||||
@"C-PEP-Info",
|
||||
@"Cache-Control",
|
||||
@"Cache-Group-Invalidation",
|
||||
@"Cache-Groups",
|
||||
@"Cache-Status",
|
||||
@"Cal-Managed-ID",
|
||||
@"CalDAV-Timezones",
|
||||
@"Capsule-Protocol",
|
||||
@"CDN-Cache-Control",
|
||||
@"CDN-Loop",
|
||||
@"Cert-Not-After",
|
||||
@"Cert-Not-Before",
|
||||
@"Clear-Site-Data",
|
||||
@"Client-Cert",
|
||||
@"Client-Cert-Chain",
|
||||
Close,
|
||||
@"CMCD-Object",
|
||||
@"CMCD-Request",
|
||||
@"CMCD-Session",
|
||||
@"CMCD-Status",
|
||||
@"CMSD-Dynamic",
|
||||
@"CMSD-Static",
|
||||
@"Concealed-Auth-Export",
|
||||
@"Configuration-Context",
|
||||
Connection,
|
||||
@"Content-Base",
|
||||
@"Content-Digest",
|
||||
@"Content-Disposition",
|
||||
@"Content-Encoding",
|
||||
@"Content-ID",
|
||||
@"Content-Language",
|
||||
@"Content-Length",
|
||||
@"Content-Location",
|
||||
@"Content-MD5",
|
||||
@"Content-Range",
|
||||
@"Content-Script-Type",
|
||||
@"Content-Security-Policy",
|
||||
@"Content-Security-Policy-Report-Only",
|
||||
@"Content-Style-Type",
|
||||
@"Content-Type",
|
||||
@"Content-Version",
|
||||
Cookie,
|
||||
Cookie2,
|
||||
@"Cross-Origin-Embedder-Policy",
|
||||
@"Cross-Origin-Embedder-Policy-Report-Only",
|
||||
@"Cross-Origin-Opener-Policy",
|
||||
@"Cross-Origin-Opener-Policy-Report-Only",
|
||||
@"Cross-Origin-Resource-Policy",
|
||||
@"CTA-Common-Access-Token",
|
||||
DASL,
|
||||
Date,
|
||||
DAV,
|
||||
@"Default-Style",
|
||||
@"Delta-Base",
|
||||
Deprecation,
|
||||
Depth,
|
||||
@"Derived-From",
|
||||
Destination,
|
||||
@"Detached-JWS",
|
||||
@"Differential-ID",
|
||||
@"Dictionary-ID",
|
||||
Digest,
|
||||
DPoP,
|
||||
@"DPoP-Nonce",
|
||||
@"Early-Data",
|
||||
@"EDIINT-Features",
|
||||
ETag,
|
||||
Expect,
|
||||
@"Expect-CT",
|
||||
Expires,
|
||||
Ext,
|
||||
Forwarded,
|
||||
From,
|
||||
GetProfile,
|
||||
Hobareg,
|
||||
Host,
|
||||
@"HTTP2-Settings",
|
||||
If,
|
||||
@"If-Match",
|
||||
@"If-Modified-Since",
|
||||
@"If-None-Match",
|
||||
@"If-Range",
|
||||
@"If-Schedule-Tag-Match",
|
||||
@"If-Unmodified-Since",
|
||||
IM,
|
||||
@"Include-Referred-Token-Binding-ID",
|
||||
Incremental,
|
||||
Isolation,
|
||||
@"Keep-Alive",
|
||||
Label,
|
||||
@"Last-Event-ID",
|
||||
@"Last-Modified",
|
||||
Link,
|
||||
@"Link-Template",
|
||||
Location,
|
||||
@"Lock-Token",
|
||||
Man,
|
||||
@"Max-Forwards",
|
||||
@"Memento-Datetime",
|
||||
Meter,
|
||||
@"Method-Check",
|
||||
@"Method-Check-Expires",
|
||||
@"MIME-Version",
|
||||
Negotiate,
|
||||
NEL,
|
||||
@"OData-EntityId",
|
||||
@"OData-Isolation",
|
||||
@"OData-MaxVersion",
|
||||
@"OData-Version",
|
||||
Opt,
|
||||
@"Optional-WWW-Authenticate",
|
||||
@"Ordering-Type",
|
||||
Origin,
|
||||
@"Origin-Agent-Cluster",
|
||||
OSCORE,
|
||||
@"OSLC-Core-Version",
|
||||
Overwrite,
|
||||
P3P,
|
||||
PEP,
|
||||
@"PEP-Info",
|
||||
@"Permissions-Policy",
|
||||
@"PICS-Label",
|
||||
@"Ping-From",
|
||||
@"Ping-To",
|
||||
Position,
|
||||
Pragma,
|
||||
Prefer,
|
||||
@"Preference-Applied",
|
||||
Priority,
|
||||
ProfileObject,
|
||||
Protocol,
|
||||
@"Protocol-Info",
|
||||
@"Protocol-Query",
|
||||
@"Protocol-Request",
|
||||
@"Proxy-Authenticate",
|
||||
@"Proxy-Authentication-Info",
|
||||
@"Proxy-Authorization",
|
||||
@"Proxy-Features",
|
||||
@"Proxy-Instruction",
|
||||
@"Proxy-Status",
|
||||
Public,
|
||||
@"Public-Key-Pins",
|
||||
@"Public-Key-Pins-Report-Only",
|
||||
Range,
|
||||
@"Redirect-Ref",
|
||||
Referer,
|
||||
@"Referer-Root",
|
||||
@"Referrer-Policy",
|
||||
Refresh,
|
||||
@"Repeatability-Client-ID",
|
||||
@"Repeatability-First-Sent",
|
||||
@"Repeatability-Request-ID",
|
||||
@"Repeatability-Result",
|
||||
@"Replay-Nonce",
|
||||
@"Reporting-Endpoints",
|
||||
@"Repr-Digest",
|
||||
@"Retry-After",
|
||||
Safe,
|
||||
@"Schedule-Reply",
|
||||
@"Schedule-Tag",
|
||||
@"Sec-Fetch-Dest",
|
||||
@"Sec-Fetch-Mode",
|
||||
@"Sec-Fetch-Site",
|
||||
@"Sec-Fetch-Storage-Access",
|
||||
@"Sec-Fetch-User",
|
||||
@"Sec-GPC",
|
||||
@"Sec-Purpose",
|
||||
@"Sec-Token-Binding",
|
||||
@"Sec-WebSocket-Accept",
|
||||
@"Sec-WebSocket-Extensions",
|
||||
@"Sec-WebSocket-Key",
|
||||
@"Sec-WebSocket-Protocol",
|
||||
@"Sec-WebSocket-Version",
|
||||
@"Security-Scheme",
|
||||
Server,
|
||||
@"Server-Timing",
|
||||
@"Set-Cookie",
|
||||
@"Set-Cookie2",
|
||||
@"Set-Txn",
|
||||
SetProfile,
|
||||
Signature,
|
||||
@"Signature-Input",
|
||||
SLUG,
|
||||
SoapAction,
|
||||
@"Status-URI",
|
||||
@"Strict-Transport-Security",
|
||||
Sunset,
|
||||
@"Surrogate-Capability",
|
||||
@"Surrogate-Control",
|
||||
TCN,
|
||||
TE,
|
||||
Timeout,
|
||||
@"Timing-Allow-Origin",
|
||||
Topic,
|
||||
Traceparent,
|
||||
Tracestate,
|
||||
Trailer,
|
||||
@"Transfer-Encoding",
|
||||
TTL,
|
||||
Upgrade,
|
||||
Urgency,
|
||||
URI,
|
||||
@"Use-As-Dictionary",
|
||||
@"User-Agent",
|
||||
@"Variant-Vary",
|
||||
Vary,
|
||||
Via,
|
||||
@"Want-Content-Digest",
|
||||
@"Want-Digest",
|
||||
@"Want-Repr-Digest",
|
||||
Warning,
|
||||
@"WWW-Authenticate",
|
||||
@"X-Content-Type-Options",
|
||||
@"X-Frame-Options",
|
||||
|
||||
/// Maps **lowercased** header names to enum values.
|
||||
pub const map: std.StaticStringMap(Known) = blk: {
|
||||
const fields = @typeInfo(Known).@"enum".fields;
|
||||
|
||||
var kvs_list: [fields.len]struct { []const u8, Known } = undefined;
|
||||
for (fields, 0..) |field, i| {
|
||||
var name_buf: [field.name.len]u8 = undefined;
|
||||
_ = std.ascii.lowerString(&name_buf, field.name);
|
||||
const name = name_buf;
|
||||
kvs_list[i] = .{ &name, @field(Known, field.name) };
|
||||
}
|
||||
|
||||
break :blk .initComptime(kvs_list);
|
||||
};
|
||||
|
||||
/// The maximum length of all known header names. Any header name longer
|
||||
/// than this cannot be a known header name.
|
||||
pub const max_known_name_len = blk: {
|
||||
const fields = @typeInfo(Known).@"enum".fields;
|
||||
|
||||
var max_len: usize = 0;
|
||||
for (fields) |field| {
|
||||
max_len = @max(max_len, field.name.len);
|
||||
}
|
||||
break :blk max_len;
|
||||
};
|
||||
|
||||
pub fn isKnown(name: []const u8) ?Known {
|
||||
if (name.len > max_known_name_len) {
|
||||
@branchHint(.unlikely);
|
||||
return null;
|
||||
}
|
||||
|
||||
var name_lowercase_buf: [max_known_name_len]u8 = undefined;
|
||||
const name_lowercase = std.ascii.lowerString(&name_lowercase_buf, name);
|
||||
return map.get(name_lowercase);
|
||||
}
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user