Skip to content

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: C++17 — 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. Behavior matches the TypeScript lib: same inputs
// produce identical outputs.

#pragma once

#include <array>
#include <cstddef>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

/// The five broad families an HTTP status code can belong to.
///
/// Modeled as a scoped enum rather than a string so the compiler can prove
/// every StatusCode carries a valid family.
enum class StatusCategory {
    Informational,
    Success,
    Redirection,
    ClientError,
    ServerError,
};

/// Stable display name, matching the TypeScript union's string values
/// (e.g. `ClientError -> "Client Error"`).
constexpr std::string_view to_string(StatusCategory category) noexcept
{
    switch (category) {
    case StatusCategory::Informational: return "Informational";
    case StatusCategory::Success:       return "Success";
    case StatusCategory::Redirection:   return "Redirection";
    case StatusCategory::ClientError:   return "Client Error";
    case StatusCategory::ServerError:   return "Server Error";
    }
    return {};  // unreachable for a valid enumerator
}

/// Parse a category from its display name.
///
/// `std::nullopt` for an unknown name is the bridge the filter relies on to
/// mirror the TypeScript "unknown category -> empty result" semantics.
constexpr std::optional<StatusCategory> category_from_string(std::string_view name) noexcept
{
    if (name == "Informational") return StatusCategory::Informational;
    if (name == "Success")       return StatusCategory::Success;
    if (name == "Redirection")   return StatusCategory::Redirection;
    if (name == "Client Error")  return StatusCategory::ClientError;
    if (name == "Server Error")  return StatusCategory::ServerError;
    return std::nullopt;
}

/// A single HTTP status code entry.
///
/// All fields are views into static storage so the whole table can live in
/// read-only memory and entries copy for free.
struct StatusCode {
    int code;
    std::string_view reason;
    StatusCategory category;
    std::string_view description;
};

/// Standard + widely-implemented HTTP status codes across 1xx–5xx.
///
/// A `constexpr` array — built at compile time and never mutated. Order is
/// grouped by category, ascending within each group.
inline constexpr std::array<StatusCode, 61> status_codes{{
    // --- 1xx Informational ---
    StatusCode{100, "Continue", StatusCategory::Informational, "The server has received the request headers and the client should proceed to send the request body."},
    StatusCode{101, "Switching Protocols", StatusCategory::Informational, "The requester has asked the server to switch protocols and the server has agreed to do so."},
    StatusCode{103, "Early Hints", StatusCategory::Informational, "Used to return some response headers before the final HTTP message so the browser can start preloading resources."},

    // --- 2xx Success ---
    StatusCode{200, "OK", StatusCategory::Success, "Standard response for a successful HTTP request."},
    StatusCode{201, "Created", StatusCategory::Success, "The request succeeded and a new resource was created."},
    StatusCode{202, "Accepted", StatusCategory::Success, "The request has been accepted for processing but is not yet complete."},
    StatusCode{203, "Non-Authoritative Information", StatusCategory::Success, "The returned metadata originated from a local or third-party copy rather than the origin server."},
    StatusCode{204, "No Content", StatusCategory::Success, "The server processed the request successfully but is not returning any content."},
    StatusCode{205, "Reset Content", StatusCategory::Success, "The server asks the client to reset the document view that sent the request."},
    StatusCode{206, "Partial Content", StatusCategory::Success, "The server is delivering only part of the resource because the client requested a byte range."},
    StatusCode{207, "Multi-Status", StatusCategory::Success, "WebDAV: conveys information about multiple resources in a single XML response."},
    StatusCode{208, "Already Reported", StatusCategory::Success, "WebDAV: the members of a DAV binding have already been enumerated in a previous reply."},
    StatusCode{226, "IM Used", StatusCategory::Success, "The server fulfilled a GET request using an instance-manipulation applied to the current instance."},

    // --- 3xx Redirection ---
    StatusCode{300, "Multiple Choices", StatusCategory::Redirection, "The request has more than one possible response; the user agent can choose among them."},
    StatusCode{301, "Moved Permanently", StatusCategory::Redirection, "This and all future requests should be directed to the given URL."},
    StatusCode{302, "Found", StatusCategory::Redirection, "The resource resides temporarily under a different URL; the method may be changed to GET."},
    StatusCode{303, "See Other", StatusCategory::Redirection, "The response to the request can be found under another URI using a GET request."},
    StatusCode{304, "Not Modified", StatusCategory::Redirection, "The resource has not been modified since the version specified by the request headers."},
    StatusCode{305, "Use Proxy", StatusCategory::Redirection, "The requested resource is available only through a proxy (deprecated)."},
    StatusCode{306, "Switch Proxy", StatusCategory::Redirection, "No longer used; originally meant subsequent requests should use a specified proxy."},
    StatusCode{307, "Temporary Redirect", StatusCategory::Redirection, "The request should be repeated with another URL; the request method must not change."},
    StatusCode{308, "Permanent Redirect", StatusCategory::Redirection, "This and all future requests should use another URL; the request method must not change."},

    // --- 4xx Client Error ---
    StatusCode{400, "Bad Request", StatusCategory::ClientError, "The server cannot process the request due to a client error such as malformed syntax."},
    StatusCode{401, "Unauthorized", StatusCategory::ClientError, "Authentication is required and has either failed or not been provided."},
    StatusCode{402, "Payment Required", StatusCategory::ClientError, "Reserved for future use; sometimes used for paywalled resources."},
    StatusCode{403, "Forbidden", StatusCategory::ClientError, "The server understood the request but refuses to authorize it."},
    StatusCode{404, "Not Found", StatusCategory::ClientError, "The requested resource could not be found on the server."},
    StatusCode{405, "Method Not Allowed", StatusCategory::ClientError, "The request method is not supported for the requested resource."},
    StatusCode{406, "Not Acceptable", StatusCategory::ClientError, "The requested resource can only generate content not acceptable per the Accept headers."},
    StatusCode{407, "Proxy Authentication Required", StatusCategory::ClientError, "The client must first authenticate itself with the proxy."},
    StatusCode{408, "Request Timeout", StatusCategory::ClientError, "The server timed out waiting for the client to send the request."},
    StatusCode{409, "Conflict", StatusCategory::ClientError, "The request could not be processed because of a conflict with the current state of the resource."},
    StatusCode{410, "Gone", StatusCategory::ClientError, "The resource is no longer available and will not be available again."},
    StatusCode{411, "Length Required", StatusCategory::ClientError, "The request did not specify the length of its content, which is required by the resource."},
    StatusCode{412, "Precondition Failed", StatusCategory::ClientError, "The server does not meet one of the preconditions given in the request headers."},
    StatusCode{413, "Content Too Large", StatusCategory::ClientError, "The request payload is larger than the server is willing or able to process."},
    StatusCode{414, "URI Too Long", StatusCategory::ClientError, "The URI provided was too long for the server to process."},
    StatusCode{415, "Unsupported Media Type", StatusCategory::ClientError, "The request uses a media type the server does not support for the resource."},
    StatusCode{416, "Range Not Satisfiable", StatusCategory::ClientError, "The portion of the resource requested in the Range header cannot be supplied by the server."},
    StatusCode{417, "Expectation Failed", StatusCategory::ClientError, "The server cannot meet the requirements of the Expect request header field."},
    StatusCode{418, "I'm a Teapot", StatusCategory::ClientError, "RFC 2324 joke status: the server refuses to brew coffee because it is, permanently, a teapot."},
    StatusCode{421, "Misdirected Request", StatusCategory::ClientError, "The request was directed at a server that is not able to produce a response."},
    StatusCode{422, "Unprocessable Content", StatusCategory::ClientError, "The server understands the content type and syntax but cannot process the contained instructions (WebDAV)."},
    StatusCode{423, "Locked", StatusCategory::ClientError, "WebDAV: the source or destination resource of the method is locked."},
    StatusCode{424, "Failed Dependency", StatusCategory::ClientError, "WebDAV: the method could not be performed because the requested action depended on another action that failed."},
    StatusCode{425, "Too Early", StatusCategory::ClientError, "The server is unwilling to risk processing a request that might be a replay."},
    StatusCode{428, "Precondition Required", StatusCategory::ClientError, "The origin server requires the request to be conditional."},
    StatusCode{429, "Too Many Requests", StatusCategory::ClientError, "The user has sent too many requests in a given time (rate limiting)."},
    StatusCode{431, "Request Header Fields Too Large", StatusCategory::ClientError, "The server is unwilling to process the request because its header fields are too large."},
    StatusCode{451, "Unavailable For Legal Reasons", StatusCategory::ClientError, "The resource is unavailable due to legal demands such as government censorship or a takedown."},

    // --- 5xx Server Error ---
    StatusCode{500, "Internal Server Error", StatusCategory::ServerError, "A generic error message: the server encountered an unexpected condition."},
    StatusCode{501, "Not Implemented", StatusCategory::ServerError, "The server does not support the functionality required to fulfill the request."},
    StatusCode{502, "Bad Gateway", StatusCategory::ServerError, "The server, acting as a gateway, received an invalid response from an upstream server."},
    StatusCode{503, "Service Unavailable", StatusCategory::ServerError, "The server is currently unavailable, typically because it is overloaded or down for maintenance."},
    StatusCode{504, "Gateway Timeout", StatusCategory::ServerError, "The server, acting as a gateway, timed out waiting for an upstream response."},
    StatusCode{505, "HTTP Version Not Supported", StatusCategory::ServerError, "The server does not support the HTTP protocol version used in the request."},
    StatusCode{506, "Variant Also Negotiates", StatusCategory::ServerError, "Transparent content negotiation for the request resulted in a circular reference."},
    StatusCode{507, "Insufficient Storage", StatusCategory::ServerError, "WebDAV: the server is unable to store the representation needed to complete the request."},
    StatusCode{508, "Loop Detected", StatusCategory::ServerError, "WebDAV: the server detected an infinite loop while processing the request."},
    StatusCode{510, "Not Extended", StatusCategory::ServerError, "Further extensions to the request are required for the server to fulfill it."},
    StatusCode{511, "Network Authentication Required", StatusCategory::ServerError, "The client must authenticate to gain network access, as with a captive portal."},
}};

namespace detail {

/// Trim ASCII whitespace from both ends of a view.
constexpr std::string_view trim(std::string_view s) noexcept
{
    constexpr auto is_space = [](char c) noexcept {
        return c == ' ' || c == '\t' || c == '\n' || c == '\r';
    };
    while (!s.empty() && is_space(s.front())) s.remove_prefix(1);
    while (!s.empty() && is_space(s.back())) s.remove_suffix(1);
    return s;
}

/// Lowercase an ASCII view — coincides with JavaScript's `toLowerCase` for
/// the ASCII text in this table.
inline std::string to_lower_ascii(std::string_view s)
{
    std::string out;
    out.reserve(s.size());
    for (char c : s) {
        out.push_back(c >= 'A' && c <= 'Z' ? static_cast<char>(c - 'A' + 'a') : c);
    }
    return out;
}

}  // namespace detail

/// 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: an
/// empty view means "no restriction"; an unknown name yields an empty result —
/// matching the TypeScript semantics. Original order is preserved.
///
/// Generic over the codes container (works with `std::array`, `std::vector`,
/// C arrays) — the C++ analogue of the TypeScript/Python "any sequence" param.
template <typename Codes>
std::vector<StatusCode> filter_codes(std::string_view query, const Codes& codes, std::string_view category = {})
{
    // Resolve the category: blank -> no filter; a name that does not parse as
    // a known family -> nothing can match, so short-circuit to empty.
    std::optional<StatusCategory> resolved;
    const std::string_view category_name = detail::trim(category);
    if (!category_name.empty()) {
        resolved = category_from_string(category_name);
        if (!resolved.has_value()) {
            return {};
        }
    }

    // The needle is lowercased once; digits and ASCII text match either way.
    const std::string needle = detail::to_lower_ascii(detail::trim(query));

    std::vector<StatusCode> matches;
    for (const StatusCode& entry : codes) {
        if (resolved.has_value() && entry.category != *resolved) {
            continue;
        }
        if (!needle.empty()) {
            // The code is matched against its decimal form, so "40" hits 404, 405, ...
            if (std::to_string(entry.code).find(needle) == std::string::npos
                && detail::to_lower_ascii(entry.reason).find(needle) == std::string::npos
                && detail::to_lower_ascii(entry.description).find(needle) == std::string::npos) {
                continue;
            }
        }
        matches.push_back(entry);
    }
    return matches;
}

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 →