337 lines
6.4 KiB
C++
337 lines
6.4 KiB
C++
#include "ehs/io/socket/Request.h"
|
|
#include "ehs/Base64.h"
|
|
|
|
namespace ehs
|
|
{
|
|
Request::Request()
|
|
: verb(Verb::GET), cType(ContentType::NONE)
|
|
{
|
|
}
|
|
|
|
Request::Request(const Verb verb, const Str_8& rsrc)
|
|
: verb(verb), rsrc(rsrc), cType(ContentType::NONE)
|
|
{
|
|
}
|
|
|
|
Request::Request(const char* data, const UInt_64 size)
|
|
: verb(Verb::POST), cType(ContentType::NONE)
|
|
{
|
|
ReadData(Str_8(data, size));
|
|
}
|
|
|
|
Request::Request(const Str_8& data)
|
|
: verb(Verb::POST), cType(ContentType::NONE)
|
|
{
|
|
ReadData(data);
|
|
}
|
|
|
|
Request& Request::operator=(const Request &req)
|
|
{
|
|
if (this == &req)
|
|
return *this;
|
|
|
|
verb = req.verb;
|
|
rsrc = req.rsrc;
|
|
queries = req.queries;
|
|
header = req.header;
|
|
cType = req.cType;
|
|
body = req.body;
|
|
|
|
return* this;
|
|
}
|
|
|
|
Verb Request::GetVerb() const
|
|
{
|
|
return verb;
|
|
}
|
|
|
|
void Request::SetContentType(const ContentType cType)
|
|
{
|
|
if (body.Size())
|
|
body.Resize(0);
|
|
|
|
this->cType = cType;
|
|
}
|
|
|
|
ContentType Request::GetContentType() const
|
|
{
|
|
return cType;
|
|
}
|
|
|
|
void Request::SetResource(const Str_8& rsrc)
|
|
{
|
|
this->rsrc = rsrc;
|
|
}
|
|
|
|
Str_8 Request::GetResource() const
|
|
{
|
|
return rsrc;
|
|
}
|
|
|
|
void Request::AddQuery(const Str_8& var, const Str_8& value)
|
|
{
|
|
queries.Push(var + "=" + value);
|
|
}
|
|
|
|
Str_8 Request::GetQuery(const Str_8& var)
|
|
{
|
|
for (UInt_64 i = 0; i < queries.Size(); ++i)
|
|
{
|
|
Vector<Str_8> data = queries[i].Split("=");
|
|
|
|
if (data[0] == var)
|
|
return data[1];
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
Vector<Str_8> Request::GetQueries() const
|
|
{
|
|
return queries;
|
|
}
|
|
|
|
void Request::BasicAuth(const Str_8& id, const Str_8& secret)
|
|
{
|
|
AddToHeader("Authorization", Str_8("Basic ") + Base64::Encode(id + ":" + secret));
|
|
}
|
|
|
|
void Request::BearerAuth(const Str_8& token)
|
|
{
|
|
AddToHeader("Authorization", "Bearer " + token);
|
|
}
|
|
|
|
void Request::BearerAuth(const Str_8& token, const Str_8& clientId)
|
|
{
|
|
AddToHeader("Authorization", "Bearer " + token);
|
|
AddToHeader("Client-Id", clientId);
|
|
}
|
|
|
|
void Request::BotAuth(const Str_8& token)
|
|
{
|
|
AddToHeader("Authorization", "Bot " + token);
|
|
}
|
|
|
|
void Request::AddToHeader(const Str_8& var, const Str_8& value)
|
|
{
|
|
header.Push(var + ": " + value);
|
|
}
|
|
|
|
Str_8 Request::GetHeader(const Str_8& var) const
|
|
{
|
|
for (UInt_64 i = 0; i < header.Size(); ++i)
|
|
{
|
|
Vector<Str_8> data = header[i].Split(": ");
|
|
|
|
if (data[0] == var)
|
|
return data[1];
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
Vector<Str_8> Request::GetHeader() const
|
|
{
|
|
return header;
|
|
}
|
|
|
|
void Request::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 Request::AddToBody(const Str_8& data)
|
|
{
|
|
if (body.Size())
|
|
{
|
|
if (cType == ContentType::APP_FORMURLENCODED)
|
|
body.Push('&');
|
|
}
|
|
|
|
body += data;
|
|
}
|
|
|
|
void Request::SetBody(const Str_8& body)
|
|
{
|
|
this->body = body;
|
|
}
|
|
|
|
Str_8 Request::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 Request::GetBody() const
|
|
{
|
|
return body;
|
|
}
|
|
|
|
Json Request::GetJson() const
|
|
{
|
|
return {body, 5};
|
|
}
|
|
|
|
Str_8 Request::FormResult() const
|
|
{
|
|
Str_8 result = VerbToStr(verb) + " " + rsrc;
|
|
|
|
if (queries.Size())
|
|
result += "?" + queries[0];
|
|
|
|
for (UInt_64 i = 1; i < queries.Size(); ++i)
|
|
result += "&" + queries[i];
|
|
|
|
result += " HTTP/1.1\r\n";
|
|
|
|
for (UInt_64 i = 0; i < header.Size(); ++i)
|
|
{
|
|
result += header[i] + "\r\n";
|
|
}
|
|
|
|
result += "Content-Type: " + ContentTypeToStr(cType) + "\r\n";
|
|
|
|
if (verb == Verb::GET)
|
|
result += "\r\n";
|
|
else
|
|
result += "Content-Length: " + Str_8::FromNum(body.Size()) + "\r\n\r\n" + body;
|
|
|
|
return result;
|
|
}
|
|
|
|
bool Request::IsValid() const
|
|
{
|
|
return rsrc.Size() || queries.Size() || header.Size() || body.Size();
|
|
}
|
|
|
|
Str_8 Request::VerbToStr(const Verb verb)
|
|
{
|
|
switch (verb)
|
|
{
|
|
case Verb::POST:
|
|
return "POST";
|
|
case Verb::GET:
|
|
return "GET";
|
|
case Verb::PUT:
|
|
return "PUT";
|
|
case Verb::DEL:
|
|
return "DELETE";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
Str_8 Request::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 Request::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 Request::ReadData(const Str_8& data)
|
|
{
|
|
Vector<Str_8> lines = data.Split("\r\n");
|
|
Vector<Str_8> meta = lines[0].Split(" ");
|
|
|
|
if (meta[0] == "POST")
|
|
verb = Verb::POST;
|
|
else if (meta[0] == "GET")
|
|
verb = Verb::GET;
|
|
else if (meta[0] == "PUT")
|
|
verb = Verb::PUT;
|
|
|
|
UInt_64 queryIndex = 0;
|
|
if (meta[1].Find("?", &queryIndex))
|
|
{
|
|
rsrc = meta[1].Sub(0, queryIndex);
|
|
cType = ContentType::APP_FORMURLENCODED;
|
|
queries = meta[1].Sub(queryIndex + 1).Split("&");
|
|
}
|
|
else
|
|
{
|
|
rsrc = meta[1];
|
|
}
|
|
|
|
for (UInt_64 i = 1; i < lines.Size(); ++i)
|
|
{
|
|
if (!lines[i].Size())
|
|
break;
|
|
|
|
Vector<Str_8> var = lines[i].Split(": ");
|
|
|
|
if (var[0] == "Content-Type")
|
|
{
|
|
cType = StrToContentType(var[1]);
|
|
continue;
|
|
}
|
|
|
|
if (var[0] == "Content-Length")
|
|
continue;
|
|
|
|
header.Push(lines[i]);
|
|
}
|
|
}
|
|
} |