HTTP Status Codes — C source
Searchable reference of all HTTP status codes with meaning, category, and usage notes.
This is the C implementation — the same logic the interactive tool runs, in a shareable, citable form.
/*
* HTTP Status Codes reference — pure, deterministic data + filter.
*
* Language: C11 — 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 dynamic allocation. Behavior matches the
* TypeScript lib: same inputs produce identical outputs.
*/
#ifndef COSMODEV_HTTP_STATUS_CODES_H
#define COSMODEV_HTTP_STATUS_CODES_H
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
/*
* The five broad families an HTTP status code can belong to.
*
* Modeled as a plain enum rather than strings so the compiler can prove every
* status_code carries a valid family. Tag values are the status-class digit
* (1xx..5xx), which keeps the table self-documenting.
*/
typedef enum {
STATUS_INFORMATIONAL = 1,
STATUS_SUCCESS = 2,
STATUS_REDIRECTION = 3,
STATUS_CLIENT_ERROR = 4,
STATUS_SERVER_ERROR = 5
} status_category;
/* Stable display name, matching the TypeScript union's string values
* (e.g. STATUS_CLIENT_ERROR -> "Client Error"). */
const char *status_category_as_str(status_category category)
{
switch (category) {
case STATUS_INFORMATIONAL: return "Informational";
case STATUS_SUCCESS: return "Success";
case STATUS_REDIRECTION: return "Redirection";
case STATUS_CLIENT_ERROR: return "Client Error";
case STATUS_SERVER_ERROR: return "Server Error";
default: return "Unknown";
}
}
/*
* Resolve a category from its display name (a trimmed span).
*
* Returns 1 and stores the value through `out` on success; returns 0 when the
* name is unknown. The filter turns 0 into an empty result, exactly as the
* TypeScript version does.
*/
int status_category_from_str(const char *name, size_t name_len, status_category *out)
{
int cat;
for (cat = STATUS_INFORMATIONAL; cat <= STATUS_SERVER_ERROR; cat++) {
const char *display = status_category_as_str((status_category)cat);
size_t display_len = strlen(display);
if (display_len == name_len && memcmp(display, name, name_len) == 0) {
if (out != NULL)
*out = (status_category)cat;
return 1;
}
}
return 0;
}
/* A single HTTP status code entry.
*
* All members point at static storage; the table below is never mutated. */
typedef struct {
int code;
const char *reason;
status_category category;
const char *description;
} status_code;
/* Standard + widely-implemented HTTP status codes across 1xx–5xx.
*
* A static const array — the table is constant. Order is grouped by category,
* ascending within each group. */
static const status_code STATUS_CODES[] = {
/* --- 1xx Informational --- */
{ 100, "Continue", STATUS_INFORMATIONAL, "The server has received the request headers and the client should proceed to send the request body." },
{ 101, "Switching Protocols", STATUS_INFORMATIONAL, "The requester has asked the server to switch protocols and the server has agreed to do so." },
{ 103, "Early Hints", STATUS_INFORMATIONAL, "Used to return some response headers before the final HTTP message so the browser can start preloading resources." },
/* --- 2xx Success --- */
{ 200, "OK", STATUS_SUCCESS, "Standard response for a successful HTTP request." },
{ 201, "Created", STATUS_SUCCESS, "The request succeeded and a new resource was created." },
{ 202, "Accepted", STATUS_SUCCESS, "The request has been accepted for processing but is not yet complete." },
{ 203, "Non-Authoritative Information", STATUS_SUCCESS, "The returned metadata originated from a local or third-party copy rather than the origin server." },
{ 204, "No Content", STATUS_SUCCESS, "The server processed the request successfully but is not returning any content." },
{ 205, "Reset Content", STATUS_SUCCESS, "The server asks the client to reset the document view that sent the request." },
{ 206, "Partial Content", STATUS_SUCCESS, "The server is delivering only part of the resource because the client requested a byte range." },
{ 207, "Multi-Status", STATUS_SUCCESS, "WebDAV: conveys information about multiple resources in a single XML response." },
{ 208, "Already Reported", STATUS_SUCCESS, "WebDAV: the members of a DAV binding have already been enumerated in a previous reply." },
{ 226, "IM Used", STATUS_SUCCESS, "The server fulfilled a GET request using an instance-manipulation applied to the current instance." },
/* --- 3xx Redirection --- */
{ 300, "Multiple Choices", STATUS_REDIRECTION, "The request has more than one possible response; the user agent can choose among them." },
{ 301, "Moved Permanently", STATUS_REDIRECTION, "This and all future requests should be directed to the given URL." },
{ 302, "Found", STATUS_REDIRECTION, "The resource resides temporarily under a different URL; the method may be changed to GET." },
{ 303, "See Other", STATUS_REDIRECTION, "The response to the request can be found under another URI using a GET request." },
{ 304, "Not Modified", STATUS_REDIRECTION, "The resource has not been modified since the version specified by the request headers." },
{ 305, "Use Proxy", STATUS_REDIRECTION, "The requested resource is available only through a proxy (deprecated)." },
{ 306, "Switch Proxy", STATUS_REDIRECTION, "No longer used; originally meant subsequent requests should use a specified proxy." },
{ 307, "Temporary Redirect", STATUS_REDIRECTION, "The request should be repeated with another URL; the request method must not change." },
{ 308, "Permanent Redirect", STATUS_REDIRECTION, "This and all future requests should use another URL; the request method must not change." },
/* --- 4xx Client Error --- */
{ 400, "Bad Request", STATUS_CLIENT_ERROR, "The server cannot process the request due to a client error such as malformed syntax." },
{ 401, "Unauthorized", STATUS_CLIENT_ERROR, "Authentication is required and has either failed or not been provided." },
{ 402, "Payment Required", STATUS_CLIENT_ERROR, "Reserved for future use; sometimes used for paywalled resources." },
{ 403, "Forbidden", STATUS_CLIENT_ERROR, "The server understood the request but refuses to authorize it." },
{ 404, "Not Found", STATUS_CLIENT_ERROR, "The requested resource could not be found on the server." },
{ 405, "Method Not Allowed", STATUS_CLIENT_ERROR, "The request method is not supported for the requested resource." },
{ 406, "Not Acceptable", STATUS_CLIENT_ERROR, "The requested resource can only generate content not acceptable per the Accept headers." },
{ 407, "Proxy Authentication Required", STATUS_CLIENT_ERROR, "The client must first authenticate itself with the proxy." },
{ 408, "Request Timeout", STATUS_CLIENT_ERROR, "The server timed out waiting for the client to send the request." },
{ 409, "Conflict", STATUS_CLIENT_ERROR, "The request could not be processed because of a conflict with the current state of the resource." },
{ 410, "Gone", STATUS_CLIENT_ERROR, "The resource is no longer available and will not be available again." },
{ 411, "Length Required", STATUS_CLIENT_ERROR, "The request did not specify the length of its content, which is required by the resource." },
{ 412, "Precondition Failed", STATUS_CLIENT_ERROR, "The server does not meet one of the preconditions given in the request headers." },
{ 413, "Content Too Large", STATUS_CLIENT_ERROR, "The request payload is larger than the server is willing or able to process." },
{ 414, "URI Too Long", STATUS_CLIENT_ERROR, "The URI provided was too long for the server to process." },
{ 415, "Unsupported Media Type", STATUS_CLIENT_ERROR, "The request uses a media type the server does not support for the resource." },
{ 416, "Range Not Satisfiable", STATUS_CLIENT_ERROR, "The portion of the resource requested in the Range header cannot be supplied by the server." },
{ 417, "Expectation Failed", STATUS_CLIENT_ERROR, "The server cannot meet the requirements of the Expect request header field." },
{ 418, "I'm a Teapot", STATUS_CLIENT_ERROR, "RFC 2324 joke status: the server refuses to brew coffee because it is, permanently, a teapot." },
{ 421, "Misdirected Request", STATUS_CLIENT_ERROR, "The request was directed at a server that is not able to produce a response." },
{ 422, "Unprocessable Content", STATUS_CLIENT_ERROR, "The server understands the content type and syntax but cannot process the contained instructions (WebDAV)." },
{ 423, "Locked", STATUS_CLIENT_ERROR, "WebDAV: the source or destination resource of the method is locked." },
{ 424, "Failed Dependency", STATUS_CLIENT_ERROR, "WebDAV: the method could not be performed because the requested action depended on another action that failed." },
{ 425, "Too Early", STATUS_CLIENT_ERROR, "The server is unwilling to risk processing a request that might be a replay." },
{ 428, "Precondition Required", STATUS_CLIENT_ERROR, "The origin server requires the request to be conditional." },
{ 429, "Too Many Requests", STATUS_CLIENT_ERROR, "The user has sent too many requests in a given time (rate limiting)." },
{ 431, "Request Header Fields Too Large", STATUS_CLIENT_ERROR, "The server is unwilling to process the request because its header fields are too large." },
{ 451, "Unavailable For Legal Reasons", STATUS_CLIENT_ERROR, "The resource is unavailable due to legal demands such as government censorship or a takedown." },
/* --- 5xx Server Error --- */
{ 500, "Internal Server Error", STATUS_SERVER_ERROR, "A generic error message: the server encountered an unexpected condition." },
{ 501, "Not Implemented", STATUS_SERVER_ERROR, "The server does not support the functionality required to fulfill the request." },
{ 502, "Bad Gateway", STATUS_SERVER_ERROR, "The server, acting as a gateway, received an invalid response from an upstream server." },
{ 503, "Service Unavailable", STATUS_SERVER_ERROR, "The server is currently unavailable, typically because it is overloaded or down for maintenance." },
{ 504, "Gateway Timeout", STATUS_SERVER_ERROR, "The server, acting as a gateway, timed out waiting for an upstream response." },
{ 505, "HTTP Version Not Supported", STATUS_SERVER_ERROR, "The server does not support the HTTP protocol version used in the request." },
{ 506, "Variant Also Negotiates", STATUS_SERVER_ERROR, "Transparent content negotiation for the request resulted in a circular reference." },
{ 507, "Insufficient Storage", STATUS_SERVER_ERROR, "WebDAV: the server is unable to store the representation needed to complete the request." },
{ 508, "Loop Detected", STATUS_SERVER_ERROR, "WebDAV: the server detected an infinite loop while processing the request." },
{ 510, "Not Extended", STATUS_SERVER_ERROR, "Further extensions to the request are required for the server to fulfill it." },
{ 511, "Network Authentication Required", STATUS_SERVER_ERROR, "The client must authenticate to gain network access, as with a captive portal." }
};
#define STATUS_CODES_LEN (sizeof STATUS_CODES / sizeof STATUS_CODES[0])
/* Lowercase an ASCII byte. */
static unsigned char ascii_lower(unsigned char c)
{
return (c >= 'A' && c <= 'Z') ? (unsigned char)(c - 'A' + 'a') : c;
}
/* Case-insensitive substring search over an ASCII span.
*
* Standard C has no strcasestr, so here is a small self-contained one; both
* sides are lowercased on the fly, so no buffer is needed for the needle. */
static int ci_contains(const char *haystack, size_t haystack_len,
const char *needle, size_t needle_len)
{
size_t i;
if (needle_len == 0)
return 1;
if (haystack_len < needle_len)
return 0;
for (i = 0; i + needle_len <= haystack_len; i++) {
size_t j = 0;
while (j < needle_len
&& ascii_lower((unsigned char)haystack[i + j]) == ascii_lower((unsigned char)needle[j]))
j++;
if (j == needle_len)
return 1;
}
return 0;
}
/* Trim ASCII whitespace from both ends of a NUL-terminated string.
*
* Sets *start past the leading whitespace and returns the span length. */
static size_t trim_span(const char *s, const char **start)
{
const char *end;
while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
s++;
*start = s;
end = s;
while (*end != '\0')
end++;
while (end > s
&& (end[-1] == ' ' || end[-1] == '\t' || end[-1] == '\n' || end[-1] == '\r'))
end--;
return (size_t)(end - s);
}
/*
* 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
* "" means "no restriction"; an unknown name yields zero results — matching
* the TypeScript semantics.
*
* Matches are written as pointers into `codes` (original order preserved)
* until `cap` is reached; the total number of matches is returned, so a caller
* can call once with out == NULL / cap == 0 to size its buffer first.
*/
size_t filter_codes(const char *query,
const status_code *codes,
size_t codes_len,
const char *category,
const status_code **out,
size_t cap)
{
status_category cat;
int have_cat = 0;
const char *needle;
size_t needle_len;
size_t matched = 0;
size_t written = 0;
size_t i;
/* Resolve the category: NULL/blank -> no filter; a name that does not
* parse as a known family -> nothing can match, so short-circuit. */
if (category != NULL) {
const char *cat_start;
size_t cat_len = trim_span(category, &cat_start);
if (cat_len != 0) {
if (!status_category_from_str(cat_start, cat_len, &cat))
return 0;
have_cat = 1;
}
}
needle_len = trim_span(query, &needle);
if (needle_len == 0)
needle = NULL;
for (i = 0; i < codes_len; i++) {
const status_code *entry = &codes[i];
if (have_cat && entry->category != cat)
continue;
if (needle != NULL) {
/* The code is matched against its decimal string form, so "40"
* hits 404, 405, ... */
char code_str[8];
int code_len = snprintf(code_str, sizeof code_str, "%d", entry->code);
if (!ci_contains(code_str, (size_t)code_len, needle, needle_len)
&& !ci_contains(entry->reason, strlen(entry->reason), needle, needle_len)
&& !ci_contains(entry->description, strlen(entry->description), needle, needle_len))
continue;
}
if (out != NULL && written < cap) {
out[written] = entry;
written++;
}
matched++;
}
return matched;
}
#endif /* COSMODEV_HTTP_STATUS_CODES_H */
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 →