HTTP Status Codes — Zig source
Searchable reference of all HTTP status codes with meaning, category, and usage notes.
This is the Zig implementation — the same logic the interactive tool runs, in a shareable, citable form.
//! HTTP Status Codes reference — pure, deterministic data + filter.
//!
//! Language: Zig 0.13 — standard library only, no third-party packages.
//! Source: CosmoDev polyglot showcase port of http-status-codes,
//! ported from src/lib/httpStatus.ts.
//! License: display source — part of CosmoDev's polyglot tool pages.
//!
//! Pure logic — no I/O, no allocation. Behavior matches the TypeScript lib:
//! same inputs produce identical outputs.
const std = @import("std");
/// The five broad families an HTTP status code can belong to.
///
/// Modeled as a fieldless enum rather than a string slice so the compiler can
/// prove every `StatusCode` carries a valid family. It is copy-sized and
/// cheap to compare.
pub const StatusCategory = enum {
informational,
success,
redirection,
client_error,
server_error,
/// Stable display name, matching the TypeScript union's string values
/// (e.g. `.client_error -> "Client Error"`).
pub fn asStr(self: StatusCategory) []const u8 {
return switch (self) {
.informational => "Informational",
.success => "Success",
.redirection => "Redirection",
.client_error => "Client Error",
.server_error => "Server Error",
};
}
/// Resolve a category from its display name; `null` when the name is
/// unknown — the filter turns that into an empty result, exactly as the
/// TypeScript version does.
pub fn fromStr(name: []const u8) ?StatusCategory {
for (std.enums.values(StatusCategory)) |category| {
if (std.mem.eql(u8, category.asStr(), name)) {
return category;
}
}
return null;
}
};
/// A single HTTP status code entry.
///
/// All fields are static slices/ints, so the whole table can live in
/// read-only memory and entries copy for free.
pub const StatusCode = struct {
code: u16,
reason: []const u8,
category: StatusCategory,
description: []const u8,
};
/// Standard + widely-implemented HTTP status codes across 1xx–5xx.
///
/// A comptime-known array — the table is constant. Order is grouped by
/// category, ascending within each group.
pub const status_codes = [_]StatusCode{
// --- 1xx Informational ---
.{ .code = 100, .reason = "Continue", .category = .informational, .description = "The server has received the request headers and the client should proceed to send the request body." },
.{ .code = 101, .reason = "Switching Protocols", .category = .informational, .description = "The requester has asked the server to switch protocols and the server has agreed to do so." },
.{ .code = 103, .reason = "Early Hints", .category = .informational, .description = "Used to return some response headers before the final HTTP message so the browser can start preloading resources." },
// --- 2xx Success ---
.{ .code = 200, .reason = "OK", .category = .success, .description = "Standard response for a successful HTTP request." },
.{ .code = 201, .reason = "Created", .category = .success, .description = "The request succeeded and a new resource was created." },
.{ .code = 202, .reason = "Accepted", .category = .success, .description = "The request has been accepted for processing but is not yet complete." },
.{ .code = 203, .reason = "Non-Authoritative Information", .category = .success, .description = "The returned metadata originated from a local or third-party copy rather than the origin server." },
.{ .code = 204, .reason = "No Content", .category = .success, .description = "The server processed the request successfully but is not returning any content." },
.{ .code = 205, .reason = "Reset Content", .category = .success, .description = "The server asks the client to reset the document view that sent the request." },
.{ .code = 206, .reason = "Partial Content", .category = .success, .description = "The server is delivering only part of the resource because the client requested a byte range." },
.{ .code = 207, .reason = "Multi-Status", .category = .success, .description = "WebDAV: conveys information about multiple resources in a single XML response." },
.{ .code = 208, .reason = "Already Reported", .category = .success, .description = "WebDAV: the members of a DAV binding have already been enumerated in a previous reply." },
.{ .code = 226, .reason = "IM Used", .category = .success, .description = "The server fulfilled a GET request using an instance-manipulation applied to the current instance." },
// --- 3xx Redirection ---
.{ .code = 300, .reason = "Multiple Choices", .category = .redirection, .description = "The request has more than one possible response; the user agent can choose among them." },
.{ .code = 301, .reason = "Moved Permanently", .category = .redirection, .description = "This and all future requests should be directed to the given URL." },
.{ .code = 302, .reason = "Found", .category = .redirection, .description = "The resource resides temporarily under a different URL; the method may be changed to GET." },
.{ .code = 303, .reason = "See Other", .category = .redirection, .description = "The response to the request can be found under another URI using a GET request." },
.{ .code = 304, .reason = "Not Modified", .category = .redirection, .description = "The resource has not been modified since the version specified by the request headers." },
.{ .code = 305, .reason = "Use Proxy", .category = .redirection, .description = "The requested resource is available only through a proxy (deprecated)." },
.{ .code = 306, .reason = "Switch Proxy", .category = .redirection, .description = "No longer used; originally meant subsequent requests should use a specified proxy." },
.{ .code = 307, .reason = "Temporary Redirect", .category = .redirection, .description = "The request should be repeated with another URL; the request method must not change." },
.{ .code = 308, .reason = "Permanent Redirect", .category = .redirection, .description = "This and all future requests should use another URL; the request method must not change." },
// --- 4xx Client Error ---
.{ .code = 400, .reason = "Bad Request", .category = .client_error, .description = "The server cannot process the request due to a client error such as malformed syntax." },
.{ .code = 401, .reason = "Unauthorized", .category = .client_error, .description = "Authentication is required and has either failed or not been provided." },
.{ .code = 402, .reason = "Payment Required", .category = .client_error, .description = "Reserved for future use; sometimes used for paywalled resources." },
.{ .code = 403, .reason = "Forbidden", .category = .client_error, .description = "The server understood the request but refuses to authorize it." },
.{ .code = 404, .reason = "Not Found", .category = .client_error, .description = "The requested resource could not be found on the server." },
.{ .code = 405, .reason = "Method Not Allowed", .category = .client_error, .description = "The request method is not supported for the requested resource." },
.{ .code = 406, .reason = "Not Acceptable", .category = .client_error, .description = "The requested resource can only generate content not acceptable per the Accept headers." },
.{ .code = 407, .reason = "Proxy Authentication Required", .category = .client_error, .description = "The client must first authenticate itself with the proxy." },
.{ .code = 408, .reason = "Request Timeout", .category = .client_error, .description = "The server timed out waiting for the client to send the request." },
.{ .code = 409, .reason = "Conflict", .category = .client_error, .description = "The request could not be processed because of a conflict with the current state of the resource." },
.{ .code = 410, .reason = "Gone", .category = .client_error, .description = "The resource is no longer available and will not be available again." },
.{ .code = 411, .reason = "Length Required", .category = .client_error, .description = "The request did not specify the length of its content, which is required by the resource." },
.{ .code = 412, .reason = "Precondition Failed", .category = .client_error, .description = "The server does not meet one of the preconditions given in the request headers." },
.{ .code = 413, .reason = "Content Too Large", .category = .client_error, .description = "The request payload is larger than the server is willing or able to process." },
.{ .code = 414, .reason = "URI Too Long", .category = .client_error, .description = "The URI provided was too long for the server to process." },
.{ .code = 415, .reason = "Unsupported Media Type", .category = .client_error, .description = "The request uses a media type the server does not support for the resource." },
.{ .code = 416, .reason = "Range Not Satisfiable", .category = .client_error, .description = "The portion of the resource requested in the Range header cannot be supplied by the server." },
.{ .code = 417, .reason = "Expectation Failed", .category = .client_error, .description = "The server cannot meet the requirements of the Expect request header field." },
.{ .code = 418, .reason = "I'm a Teapot", .category = .client_error, .description = "RFC 2324 joke status: the server refuses to brew coffee because it is, permanently, a teapot." },
.{ .code = 421, .reason = "Misdirected Request", .category = .client_error, .description = "The request was directed at a server that is not able to produce a response." },
.{ .code = 422, .reason = "Unprocessable Content", .category = .client_error, .description = "The server understands the content type and syntax but cannot process the contained instructions (WebDAV)." },
.{ .code = 423, .reason = "Locked", .category = .client_error, .description = "WebDAV: the source or destination resource of the method is locked." },
.{ .code = 424, .reason = "Failed Dependency", .category = .client_error, .description = "WebDAV: the method could not be performed because the requested action depended on another action that failed." },
.{ .code = 425, .reason = "Too Early", .category = .client_error, .description = "The server is unwilling to risk processing a request that might be a replay." },
.{ .code = 428, .reason = "Precondition Required", .category = .client_error, .description = "The origin server requires the request to be conditional." },
.{ .code = 429, .reason = "Too Many Requests", .category = .client_error, .description = "The user has sent too many requests in a given time (rate limiting)." },
.{ .code = 431, .reason = "Request Header Fields Too Large", .category = .client_error, .description = "The server is unwilling to process the request because its header fields are too large." },
.{ .code = 451, .reason = "Unavailable For Legal Reasons", .category = .client_error, .description = "The resource is unavailable due to legal demands such as government censorship or a takedown." },
// --- 5xx Server Error ---
.{ .code = 500, .reason = "Internal Server Error", .category = .server_error, .description = "A generic error message: the server encountered an unexpected condition." },
.{ .code = 501, .reason = "Not Implemented", .category = .server_error, .description = "The server does not support the functionality required to fulfill the request." },
.{ .code = 502, .reason = "Bad Gateway", .category = .server_error, .description = "The server, acting as a gateway, received an invalid response from an upstream server." },
.{ .code = 503, .reason = "Service Unavailable", .category = .server_error, .description = "The server is currently unavailable, typically because it is overloaded or down for maintenance." },
.{ .code = 504, .reason = "Gateway Timeout", .category = .server_error, .description = "The server, acting as a gateway, timed out waiting for an upstream response." },
.{ .code = 505, .reason = "HTTP Version Not Supported", .category = .server_error, .description = "The server does not support the HTTP protocol version used in the request." },
.{ .code = 506, .reason = "Variant Also Negotiates", .category = .server_error, .description = "Transparent content negotiation for the request resulted in a circular reference." },
.{ .code = 507, .reason = "Insufficient Storage", .category = .server_error, .description = "WebDAV: the server is unable to store the representation needed to complete the request." },
.{ .code = 508, .reason = "Loop Detected", .category = .server_error, .description = "WebDAV: the server detected an infinite loop while processing the request." },
.{ .code = 510, .reason = "Not Extended", .category = .server_error, .description = "Further extensions to the request are required for the server to fulfill it." },
.{ .code = 511, .reason = "Network Authentication Required", .category = .server_error, .description = "The client must authenticate to gain network access, as with a captive portal." },
};
/// Lowercase an ASCII byte.
fn asciiLower(c: u8) u8 {
return if (c >= 'A' and c <= 'Z') c + ('a' - 'A') else c;
}
/// Case-insensitive substring search over ASCII text.
///
/// Both sides are lowercased on the fly, so no buffer is needed for the
/// needle — the whole filter stays allocation-free.
fn containsIgnoreCase(haystack: []const u8, needle: []const u8) bool {
if (needle.len == 0) return true;
if (haystack.len < needle.len) return false;
var i: usize = 0;
while (i + needle.len <= haystack.len) : (i += 1) {
var j: usize = 0;
while (j < needle.len and asciiLower(haystack[i + j]) == asciiLower(needle[j])) : (j += 1) {}
if (j == needle.len) return true;
}
return false;
}
/// Filter status codes by a free-text query and an optional category.
///
/// `query` is matched case-insensitively against the numeric code (as a
/// decimal string), the reason phrase, and the description. An
/// empty/whitespace query returns every code in the pool. `category`
/// restricts the pool first: `null` (or blank) means "no restriction"; an
/// unknown name yields zero results — matching the TypeScript semantics.
///
/// Caller-owned buffer, no allocator: matching pointers are written into
/// `out` in the original order until it is full, and the total number of
/// matches is returned — pass `out.len == 0` first to size the buffer.
pub fn filterCodes(
query: []const u8,
codes: []const StatusCode,
category: ?[]const u8,
out: []const *const StatusCode,
) usize {
// Resolve the category: null/blank -> no filter; a name that does not
// parse as a known family -> nothing can match, so short-circuit.
var cat: ?StatusCategory = null;
if (category) |raw| {
const name = std.mem.trim(u8, raw, " \t\r\n");
if (name.len != 0) {
cat = StatusCategory.fromStr(name) orelse return 0;
}
}
const needle = std.mem.trim(u8, query, " \t\r\n");
var matched: usize = 0;
var written: usize = 0;
for (codes) |*entry| {
if (cat) |wanted| {
if (entry.category != wanted) continue;
}
if (needle.len != 0) {
// The code is matched against its decimal form, so "40" hits 404, 405, ...
var code_buf: [5]u8 = undefined; // u16 max is 65535 — five digits
const code_str = std.fmt.bufPrint(&code_buf, "{d}", .{entry.code}) catch unreachable;
if (!containsIgnoreCase(code_str, needle) and
!containsIgnoreCase(entry.reason, needle) and
!containsIgnoreCase(entry.description, needle))
{
continue;
}
}
if (written < out.len) {
out[written] = entry;
written += 1;
}
matched += 1;
}
return matched;
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →