pub const Client = @import("http/Client.zig");
pub const Server = @import("http/Server.zig");
pub const protocol = @import("http/protocol.zig");
const headers = @import("http/Headers.zig");
pub const Headers = headers.Headers;
pub const Field = headers.Field;
pub const Version = enum {
@"HTTP/1.0",
@"HTTP/1.1",
};
pub const Method = enum {
GET,
HEAD,
POST,
PUT,
DELETE,
CONNECT,
OPTIONS,
TRACE,
PATCH,
pub fn requestHasBody(self: Method) bool {
return switch (self) {
.POST, .PUT, .PATCH => true,
.GET, .HEAD, .DELETE, .CONNECT, .OPTIONS, .TRACE => false,
};
}
pub fn responseHasBody(self: Method) bool {
return switch (self) {
.GET, .POST, .DELETE, .CONNECT, .OPTIONS, .PATCH => true,
.HEAD, .PUT, .TRACE => false,
};
}
pub fn safe(self: Method) bool {
return switch (self) {
.GET, .HEAD, .OPTIONS, .TRACE => true,
.POST, .PUT, .DELETE, .CONNECT, .PATCH => false,
};
}
pub fn idempotent(self: Method) bool {
return switch (self) {
.GET, .HEAD, .PUT, .DELETE, .OPTIONS, .TRACE => true,
.CONNECT, .POST, .PATCH => false,
};
}
pub fn cacheable(self: Method) bool {
return switch (self) {
.GET, .HEAD => true,
.POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .TRACE, .PATCH => false,
};
}
};
pub const Status = enum(u10) {
@"continue" = 100,
switching_protocols = 101,
processing = 102,
early_hints = 103,
ok = 200,
created = 201,
accepted = 202,
non_authoritative_info = 203,
no_content = 204,
reset_content = 205,
partial_content = 206,
multi_status = 207,
already_reported = 208,
im_used = 226,
multiple_choice = 300,
moved_permanently = 301,
found = 302,
see_other = 303,
not_modified = 304,
use_proxy = 305,
temporary_redirect = 307,
permanent_redirect = 308,
bad_request = 400,
unauthorized = 401,
payment_required = 402,
forbidden = 403,
not_found = 404,
method_not_allowed = 405,
not_acceptable = 406,
proxy_auth_required = 407,
request_timeout = 408,
conflict = 409,
gone = 410,
length_required = 411,
precondition_failed = 412,
payload_too_large = 413,
uri_too_long = 414,
unsupported_media_type = 415,
range_not_satisfiable = 416,
expectation_failed = 417,
teapot = 418,
misdirected_request = 421,
unprocessable_entity = 422,
locked = 423,
failed_dependency = 424,
too_early = 425,
upgrade_required = 426,
precondition_required = 428,
too_many_requests = 429,
request_header_fields_too_large = 431,
unavailable_for_legal_reasons = 451,
internal_server_error = 500,
not_implemented = 501,
bad_gateway = 502,
service_unavailable = 503,
gateway_timeout = 504,
http_version_not_supported = 505,
variant_also_negotiates = 506,
insufficient_storage = 507,
loop_detected = 508,
not_extended = 510,
network_authentication_required = 511,
_,
pub fn phrase(self: Status) ?[]const u8 {
return switch (self) {
.@"continue" => "Continue",
.switching_protocols => "Switching Protocols",
.processing => "Processing",
.early_hints => "Early Hints",
.ok => "OK",
.created => "Created",
.accepted => "Accepted",
.non_authoritative_info => "Non-Authoritative Information",
.no_content => "No Content",
.reset_content => "Reset Content",
.partial_content => "Partial Content",
.multi_status => "Multi-Status",
.already_reported => "Already Reported",
.im_used => "IM Used",
.multiple_choice => "Multiple Choice",
.moved_permanently => "Moved Permanently",
.found => "Found",
.see_other => "See Other",
.not_modified => "Not Modified",
.use_proxy => "Use Proxy",
.temporary_redirect => "Temporary Redirect",
.permanent_redirect => "Permanent Redirect",
.bad_request => "Bad Request",
.unauthorized => "Unauthorized",
.payment_required => "Payment Required",
.forbidden => "Forbidden",
.not_found => "Not Found",
.method_not_allowed => "Method Not Allowed",
.not_acceptable => "Not Acceptable",
.proxy_auth_required => "Proxy Authentication Required",
.request_timeout => "Request Timeout",
.conflict => "Conflict",
.gone => "Gone",
.length_required => "Length Required",
.precondition_failed => "Precondition Failed",
.payload_too_large => "Payload Too Large",
.uri_too_long => "URI Too Long",
.unsupported_media_type => "Unsupported Media Type",
.range_not_satisfiable => "Range Not Satisfiable",
.expectation_failed => "Expectation Failed",
.teapot => "I'm a teapot",
.misdirected_request => "Misdirected Request",
.unprocessable_entity => "Unprocessable Entity",
.locked => "Locked",
.failed_dependency => "Failed Dependency",
.too_early => "Too Early",
.upgrade_required => "Upgrade Required",
.precondition_required => "Precondition Required",
.too_many_requests => "Too Many Requests",
.request_header_fields_too_large => "Request Header Fields Too Large",
.unavailable_for_legal_reasons => "Unavailable For Legal Reasons",
.internal_server_error => "Internal Server Error",
.not_implemented => "Not Implemented",
.bad_gateway => "Bad Gateway",
.service_unavailable => "Service Unavailable",
.gateway_timeout => "Gateway Timeout",
.http_version_not_supported => "HTTP Version Not Supported",
.variant_also_negotiates => "Variant Also Negotiates",
.insufficient_storage => "Insufficient Storage",
.loop_detected => "Loop Detected",
.not_extended => "Not Extended",
.network_authentication_required => "Network Authentication Required",
else => return null,
};
}
pub const Class = enum {
informational,
success,
redirect,
client_error,
server_error,
};
pub fn class(self: Status) Class {
return switch (@enumToInt(self)) {
100...199 => .informational,
200...299 => .success,
300...399 => .redirect,
400...499 => .client_error,
else => .server_error,
};
}
test {
try std.testing.expectEqualStrings("OK", Status.ok.phrase().?);
try std.testing.expectEqualStrings("Not Found", Status.not_found.phrase().?);
}
test {
try std.testing.expectEqual(@as(?Status.Class, Status.Class.success), Status.ok.class());
try std.testing.expectEqual(@as(?Status.Class, Status.Class.client_error), Status.not_found.class());
}
};
pub const TransferEncoding = enum {
chunked,
};
pub const ContentEncoding = enum {
compress,
deflate,
gzip,
zstd,
};
pub const Connection = enum {
keep_alive,
close,
};
const std = @import("std.zig");
test {
_ = Client;
_ = Method;
_ = Status;
_ = @import("http/test.zig");
}