Adjusted workflow.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 1m8s
Build & Release / Linux-AMD64-Build (push) Successful in 1m30s
Build & Release / Linux-AARCH64-Build (push) Successful in 3m21s

This commit is contained in:
2024-02-05 22:25:30 -08:00
commit bcd71cf2b5
251 changed files with 45909 additions and 0 deletions

403
src/io/socket/Response.cpp Normal file
View File

@@ -0,0 +1,403 @@
#include "ehs/io/socket/Response.h"
namespace ehs
{
Response::Response(const UInt_32 code, const Str_8& server)
: code(code), server(server), cType(ContentType::NONE)
{
}
Response::Response(const char* data, const UInt_64 size)
: code(0), cType(ContentType::NONE)
{
ReadData(Str_8(data, size));
}
Response::Response(const Str_8& data)
: code(0), cType(ContentType::NONE)
{
ReadData(data);
}
Response::Response()
: code(0), cType(ContentType::NONE)
{
}
Response& Response::operator=(const Response& res)
{
if (this == &res)
return *this;
code = res.code;
server = res.server;
cType = res.cType;
header = res.header;
body = res.body;
return *this;
}
void Response::SetCode(const UInt_32 code)
{
this->code = code;
}
UInt_32 Response::GetCode() const
{
return code;
}
void Response::SetServer(const Str_8& server)
{
this->server = server;
}
Str_8 Response::GetServer() const
{
return server;
}
void Response::SetContentType(const ContentType cType)
{
this->cType = cType;
}
ContentType Response::GetContentType() const
{
return cType;
}
void Response::AddToHeader(const Str_8& var, const Str_8& value)
{
header.Push(var + ": " + value);
}
Str_8 Response::GetHeader(const Str_8& var) const
{
Str_8 lIdentity = var.GetLower();
for (UInt_64 i = 0; i < header.Size(); ++i)
{
Vector<Str_8> data = header[i].Split(": ");
if (data[0].GetLower() == lIdentity)
return data[1];
}
return "";
}
Vector<Str_8> Response::GetHeader() const
{
return header;
}
void Response::AddToBody(const Str_8& var, const Str_8& value)
{
if (body.Size())
{
if (cType == ContentType::APP_FORMURLENCODED)
body.Push('&');
}
body += var;
if (cType == ContentType::APP_FORMURLENCODED)
body += "=";
body += value;
}
void Response::AddToBody(const Str_8& data)
{
if (body.Size())
{
if (cType == ContentType::APP_FORMURLENCODED)
body.Push('&');
}
body += data;
}
void Response::SetBody(const Str_8& body)
{
this->body = body;
}
Str_8 Response::GetVar(const Str_8& var) const
{
Vector<Str_8> vars;
if (cType == ContentType::APP_FORMURLENCODED)
vars = body.Split("&");
for (UInt_64 i = 0; i < vars.Size(); ++i)
{
Vector<Str_8> data = vars[i].Split("=");
if (data[0] == var)
return data[1];
}
return "";
}
Str_8 Response::GetBody() const
{
return body;
}
Json Response::GetJson() const
{
return {body, 5};
}
Str_8 Response::FormResult() const
{
Str_8 result = "HTTP/1.1 " + Str_8::FromNum(code) + " " + CodeToStr(code) + "\r\nServer: " + server + "\r\n";
for (UInt_64 i = 0; i < header.Size(); ++i)
{
if (header[i].Find("Content-Length", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
continue;
else if (header[i].Find("Server", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
continue;
else if (header[i].Find("Content-Type", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
continue;
result += header[i] + "\r\n";
}
result += "Content-Type: " + ContentTypeToStr(cType) + "\r\nContent-Length: " + Str_8::FromNum(body.Size()) + "\r\n\r\n" + body;
return result;
}
bool Response::IsValid() const
{
return server.Size() || header.Size() || body.Size();
}
Str_8 Response::CodeToStr(const UInt_32 code)
{
if (code == 100)
return "Continue";
else if (code == 101)
return "Switching Protocols";
else if (code == 102)
return "Processing (WebDAV)";
else if (code == 200)
return "OK";
else if (code == 201)
return "Created";
else if (code == 202)
return "Accepted";
else if (code == 203)
return "Non-Authoritative Information";
else if (code == 204)
return "No Content";
else if (code == 205)
return "Reset Content";
else if (code == 206)
return "Partial Content";
else if (code == 207)
return "Multi-Status (WebDAV)";
else if (code == 208)
return "Already Reported (WebDAV)";
else if (code == 226)
return "IM Used";
else if (code == 300)
return "Multiple Choices";
else if (code == 301)
return "Moved Permanently";
else if (code == 302)
return "Found";
else if (code == 303)
return "See Others";
else if (code == 304)
return "Not Modified";
else if (code == 305)
return "Use Proxy";
else if (code == 306)
return "(Unused)";
else if (code == 307)
return "Temporary Redirect";
else if (code == 308)
return "Permanent Redirect (experimental)";
else if (code == 400)
return "Bad Request";
else if (code == 401)
return "Unauthorized";
else if (code == 402)
return "Payment Required";
else if (code == 403)
return "Forbidden";
else if (code == 404)
return "Not Found";
else if (code == 405)
return "Method Not Allowed";
else if (code == 406)
return "Not Acceptable";
else if (code == 407)
return "Proxy Authentication Required";
else if (code == 408)
return "Request Timeout";
else if (code == 409)
return "Conflict";
else if (code == 410)
return "Gone";
else if (code == 411)
return "Length Required";
else if (code == 412)
return "Precondition Failed";
else if (code == 413)
return "Request Entity Too Large";
else if (code == 414)
return "Request-URI Too Long";
else if (code == 415)
return "Unsupported Media Type";
else if (code == 416)
return "Requested Range Not Satisfiable";
else if (code == 417)
return "Expectation Failed";
else if (code == 418)
return "I'm a teapot (RFC 2324)";
else if (code == 420)
return "Enhance Your Calm (Twitter)";
else if (code == 422)
return "Unprocessable Entity (WebDAV)";
else if (code == 423)
return "Locked (WebDAV)";
else if (code == 424)
return "Failed Dependency (Nginx)";
else if (code == 425)
return "Reserved for WebDAV";
else if (code == 426)
return "Upgrade Required";
else if (code == 428)
return "Precondition Required";
else if (code == 429)
return "Too Many Requests";
else if (code == 431)
return "Request Header Fields Too Large";
else if (code == 444)
return "No Response (Nginx)";
else if (code == 449)
return "Retry With (Microsoft)";
else if (code == 450)
return "Blocked by Windows Parental Controls (Microsoft)";
else if (code == 451)
return "Unavailable For Legal Reasons";
else if (code == 499)
return "Client Closed Request (Nginx)";
else if (code == 500)
return "Internal Server Error";
else if (code == 501)
return "Not Implemented";
else if (code == 502)
return "Bad Gateway";
else if (code == 503)
return "Service Unavailable";
else if (code == 504)
return "Gateway Timeout";
else if (code == 505)
return "HTTP Version Not Supported";
else if (code == 506)
return "Variant Also Negotiates (Experimental)";
else if (code == 507)
return "Insufficient Storage (WebDAV)";
else if (code == 508)
return "Loop Detected (WebDAV)";
else if (code == 509)
return "Bandwidth Limit Exceeded (Apache)";
else if (code == 510)
return "Not Extended";
else if (code == 511)
return "Network Authentication Required";
else if (code == 598)
return "Network read timeout error";
else if (code == 599)
return "Network connect timeout error";
else
return "Unused Status Code";
}
Str_8 Response::ContentTypeToStr(const ContentType cType)
{
switch (cType)
{
case ContentType::APP_MULTIPART_FORMDATA:
return "multipart/form-data";
case ContentType::APP_FORMURLENCODED:
return "application/x-www-form-urlencoded";
case ContentType::APP_JAVASCRIPT:
return "application/javascript";
case ContentType::APP_JSON:
return "application/json";
case ContentType::APP_XML:
return "application/xml";
case ContentType::TEXT_PLAIN:
return "text/plain";
case ContentType::TEXT_HTML:
return "text/html";
case ContentType::TEXT_XML:
return "text/xml";
default:
return "";
}
}
ContentType Response::StrToContentType(const Str_8& value)
{
if (value == "multipart/form-data")
return ContentType::APP_MULTIPART_FORMDATA;
else if (value == "application/x-www-form-urlencoded")
return ContentType::APP_FORMURLENCODED;
else if (value == "application/javascript")
return ContentType::APP_JAVASCRIPT;
else if (value == "application/json")
return ContentType::APP_JSON;
else if (value == "application/xml")
return ContentType::APP_XML;
else if (value == "text/plain")
return ContentType::TEXT_PLAIN;
else if (value == "text/html")
return ContentType::TEXT_HTML;
else if (value == "text/xml")
return ContentType::TEXT_XML;
else
return ContentType::NONE;
}
void Response::ReadData(const Str_8& data)
{
Vector<Str_8> lines = data.Split("\r\n");
Vector<Str_8> meta = lines[0].Split(" ");
code = meta[1].ToDecimal<UInt_32>();
for (UInt_64 i = 1; i < lines.Size(); ++i)
{
if (!lines[i].Size())
break;
Vector<Str_8> var = lines[i].Split(": ");
if (var[0].GetLower() == "server")
{
server = var[1];
continue;
}
else if (var[0].GetLower() == "content-type")
{
Vector<Str_8> ctData = var[1].Split(";");
cType = StrToContentType(ctData[0].GetLower());
continue;
}
header.Push(lines[i]);
}
}
}