VWeb/Source/Response.cpp

112 lines
5.3 KiB
C++

#include <VWeb.h>
namespace VWeb {
// clang-format off
static std::unordered_map<HttpStatusCode, std::string> 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
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<std::string> &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.clear(); }
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