2022-08-23 14:13:21 +02:00
|
|
|
#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
|
2022-08-23 16:40:57 +02:00
|
|
|
|
|
|
|
Ref<Response> Response::FromCode(HttpStatusCode code) {
|
|
|
|
auto response = CreateRef<Response>();
|
|
|
|
response->SetStatus(code);
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2022-08-23 14:13:21 +02:00
|
|
|
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; }
|
|
|
|
|
2022-09-10 15:09:18 +02:00
|
|
|
void Response::Reset() {
|
|
|
|
m_Content = {};
|
|
|
|
}
|
2022-08-23 14:13:21 +02:00
|
|
|
|
|
|
|
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
|