#include namespace VWeb { // clang-format off static std::unordered_map s_HTTPCodeToString = { {HttpStatusCode::Continue, "100 Continue"}, {HttpStatusCode::SwitchingProtocols, "101 Switching Protocols"}, {HttpStatusCode::Processing, "102 Processing"}, {HttpStatusCode::EarlyHints, "103 Early Hints"}, {HttpStatusCode::OK, "200 OK"}, {HttpStatusCode::Created, "201 Created"}, {HttpStatusCode::Accepted, "202 Accepted"}, {HttpStatusCode::NonAuthoritativeInformation,"203 Non-Authoritative Information"}, {HttpStatusCode::NoContent, "204 No Content"}, {HttpStatusCode::ResetContent, "205 Reset Content"}, {HttpStatusCode::PartialContent, "206 Partial Content"}, {HttpStatusCode::MultiStatus, "207 Multi-Status"}, {HttpStatusCode::AlreadyReported, "208 Already Reported"}, {HttpStatusCode::IMUsed, "226 IM Used"}, {HttpStatusCode::MultipleChoices, "300 Multiple Choices"}, {HttpStatusCode::MovedPermanently, "301 Moved Permanently"}, {HttpStatusCode::Found, "302 Found"}, {HttpStatusCode::SeeOther, "303 See Other"}, {HttpStatusCode::NotModified, "304 Not Modified"}, {HttpStatusCode::UseProxy, "305 Use Proxy"}, {HttpStatusCode::TemporaryRedirect, "307 Temporary Redirect"}, {HttpStatusCode::PermanentRedirect, "308 Permanent Redirect"}, {HttpStatusCode::BadRequest, "400 Bad Request"}, {HttpStatusCode::Unauthorized, "401 Unauthorized"}, {HttpStatusCode::PaymentRequired, "402 Payment Required"}, {HttpStatusCode::Forbidden, "403 Forbidden"}, {HttpStatusCode::NotFound, "404 Not Found"}, {HttpStatusCode::MethodNotAllowed, "405 Method Not Allowed"}, {HttpStatusCode::NotAcceptable, "406 Not Acceptable"}, {HttpStatusCode::ProxyAuthenticationRequired,"407 Proxy Authentication Required"}, {HttpStatusCode::RequestTimeout, "408 Request Timeout"}, {HttpStatusCode::Conflict, "409 Conflict"}, {HttpStatusCode::Gone, "410 Gone"}, {HttpStatusCode::LengthRequired, "411 Length Required"}, {HttpStatusCode::PreconditionFailed, "412 Precondition Failed"}, {HttpStatusCode::PayloadTooLarge, "413 Payload Too Large"}, {HttpStatusCode::URITooLong, "414 URI Too Long"}, {HttpStatusCode::UnsupportedMediaType, "415 Unsupported Media Type"}, {HttpStatusCode::RangeNotSatisfiable, "416 Range Not Satisfiable"}, {HttpStatusCode::ExpectationFailed, "417 Expectation Failed"}, {HttpStatusCode::ImATeapot, "418 I'm a teapot"}, {HttpStatusCode::UnprocessableEntity, "422 Unprocessable Entity"}, {HttpStatusCode::Locked, "423 Locked"}, {HttpStatusCode::FailedDependency, "424 Failed Dependency"}, {HttpStatusCode::UpgradeRequired, "426 Upgrade Required"}, {HttpStatusCode::PreconditionRequired, "428 Precondition Required"}, {HttpStatusCode::TooManyRequests, "429 Too Many Requests"}, {HttpStatusCode::RequestHeaderFieldsTooLarge,"431 Request Header Fields Too Large"}, {HttpStatusCode::UnavailableForLegalReasons,"451 Unavailable For Legal Reasons"}, {HttpStatusCode::InternalServerError, "500 Internal Server Error"}, {HttpStatusCode::NotImplemented, "501 Not Implemented"}, {HttpStatusCode::BadGateway, "502 Bad Gateway"}, {HttpStatusCode::ServiceUnavailable, "503 Service Unavailable"}, {HttpStatusCode::GatewayTimeout, "504 Gateway Time-out"}, {HttpStatusCode::HTTPVersionNotSupported, "505 HTTP Version Not Supported"}, {HttpStatusCode::VariantAlsoNegotiates, "506 Variant Also Negotiates"}, {HttpStatusCode::InsufficientStorage, "507 Insufficient Storage"}, {HttpStatusCode::LoopDetected, "508 Loop Detected"}, {HttpStatusCode::NotExtended, "510 Not Extended"}, {HttpStatusCode::NetworkAuthenticationRequired,"511 Network Authentication Required"} }; // clang-format on Ref Response::FromCode(HttpStatusCode code) { auto response = CreateRef(); response->SetStatus(code); return response; } std::string Response::GetResponse() { std::string content = m_Content.str(); auto headData = TransformHeaders(content); auto outContent = std::string(headData + content); Length = content.length(); return outContent; } void Response::SetHeader(const std::string &key, const std::string &value) { m_Headers[key].Set(value); } void Response::SetHeader(const std::string &key, ParameterValue &value) { m_Headers[key] = value; } void Response::AddHeaders(const std::string &key, const Vector &values) { auto &element = m_Headers[key]; for (const auto &value : values) element.Add(value); } void Response::AddHeader(const std::string &key, const std::string &value) { m_Headers[key].Add(value); } void Response::SetType(const std::string &type) { m_Type = type; } void Response::AddContent(const std::string &data) { m_Content << data; } void Response::SetStatus(HttpStatusCode statusCode) { Status = statusCode; } void Response::SetMethod(HttpMethod method) { Method = method; } void Response::Reset() { m_Content = {}; } std::string Response::TransformHeaders(const std::string &content) { std::ostringstream stream; stream << "HTTP/1.1 " << s_HTTPCodeToString[Status] << "\n"; stream << "content-type: " << m_Type << "\n"; stream << "content-length: " << content.length() << "\n"; for (auto &[key, value] : m_Headers) { for (auto &val : value.Values()) { stream << key << ": " << val << "\n"; } } stream << CookieData->TransformToHeader(); stream << "\n"; return stream.str(); } } // namespace VWeb