Added Post Body Parsing
This commit is contained in:
parent
afd8f4d999
commit
5c8c4e86b2
14 changed files with 139 additions and 49 deletions
|
|
@ -103,5 +103,6 @@ void Cookies::CookieToString(std::stringstream &stream, Cookie &cookie) {
|
|||
view << "; SameSite=" << sameSiteValue;
|
||||
}
|
||||
view << "\n";
|
||||
stream << view.str();
|
||||
}
|
||||
} // namespace VWeb
|
||||
|
|
@ -68,7 +68,7 @@ PreMiddleWareReturn SessionManager::PreHandle(Request &request) {
|
|||
return {};
|
||||
}
|
||||
|
||||
bool SessionManager::PostHandle(const Request &request, Response &response) {
|
||||
bool SessionManager::PostHandle(Request &request, Response &response) {
|
||||
if (response.SessionData->Id.empty() &&
|
||||
response.SessionData->ContainsData()) {
|
||||
response.SessionData->Update();
|
||||
|
|
@ -80,8 +80,9 @@ bool SessionManager::PostHandle(const Request &request, Response &response) {
|
|||
}
|
||||
m_Sessions[response.SessionData->Id] = response.SessionData;
|
||||
auto &sidCookie = response.CookieData->Get("sid");
|
||||
sidCookie.Name = "sid";
|
||||
sidCookie.HttpOnly = true;
|
||||
sidCookie.Secure = true;
|
||||
sidCookie.SameSite = CookieSameSite::Strict;
|
||||
sidCookie.Value = response.SessionData->Id;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -101,7 +102,7 @@ void SessionManager::GC() {
|
|||
#pragma endregion SESSION
|
||||
#pragma region COOKIES
|
||||
PreMiddleWareReturn CookieManager::PreHandle(Request &request) {
|
||||
auto &cookieHeaders = request.Header("Cookie");
|
||||
auto &cookieHeaders = request.Header("cookie");
|
||||
auto &cookies = request.CookieData;
|
||||
if (cookieHeaders.Size() > 0) {
|
||||
auto &values = cookieHeaders.Values();
|
||||
|
|
@ -118,4 +119,4 @@ PreMiddleWareReturn CookieManager::PreHandle(Request &request) {
|
|||
return {};
|
||||
}
|
||||
#pragma endregion COOKIES
|
||||
} // namespace VWeb
|
||||
} // namespace VWeb
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ bool ParseRequest(Ref<Request> &request) {
|
|||
if (index != std::string::npos) {
|
||||
auto key = line.substr(0, index);
|
||||
String::Trim(key);
|
||||
String::ToLowerCase(key);
|
||||
request->Header(key).Add(String::TrimCopy(line.substr(index + 1)));
|
||||
} else if (line.find("HTTP")) {
|
||||
auto headers = String::Split(line, " ");
|
||||
|
|
@ -41,6 +42,49 @@ bool ParseRequest(Ref<Request> &request) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ParseParameterString(Request &req, const std::string &toParse) {
|
||||
auto data = String::Split(toParse, "&");
|
||||
for (auto &item : data) {
|
||||
auto d = String::Split(item, "=", 1);
|
||||
req.Parameter(d[0]).Add(d.size() > 1 ? d[1] : "true");
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetPostBody(const std::string& originalBody)
|
||||
{
|
||||
auto body = String::Split(originalBody, "\r\n\r\n", 1);
|
||||
if (body.size() > 1 && ! body[body.size() - 1].empty())
|
||||
return String::TrimCopy(String::UrlDecode(body[body.size() - 1]));
|
||||
return {};
|
||||
}
|
||||
|
||||
void ParseParameters(Request &request, RequestHandler &requestHandler) {
|
||||
auto &uri = request.URI;
|
||||
size_t hasURLParameters = uri.find('?');
|
||||
if (hasURLParameters != std::string::npos) {
|
||||
ParseParameterString(request, uri.substr(hasURLParameters + 1));
|
||||
request.URI = uri.substr (0, hasURLParameters);
|
||||
}
|
||||
|
||||
if (request.Method == HttpMethod::HEAD || request.Method == HttpMethod::GET ||
|
||||
request.Method == HttpMethod::OPTIONS)
|
||||
return;
|
||||
|
||||
// POST :D
|
||||
auto &contentType = request.Header("content-type");
|
||||
if (contentType.Size() == 0)
|
||||
return;
|
||||
auto &key = contentType.GetFirst();
|
||||
if (key == "application/x-www-form-urlencoded") {
|
||||
ParseParameterString(request, GetPostBody(request.Body));
|
||||
} else {
|
||||
if (requestHandler.HasBodyParser(key)) {
|
||||
auto &func = requestHandler.GetBodyParser(key);
|
||||
func(request, GetPostBody(request.Body));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RequestJob : public WorkerJob {
|
||||
Ref<Request> MRequest{};
|
||||
Ref<Router> MRouter{};
|
||||
|
|
@ -53,6 +97,7 @@ struct RequestJob : public WorkerJob {
|
|||
SocketUtils::Close(MRequest->ID);
|
||||
return;
|
||||
}
|
||||
ParseParameters(*MRequest, *MRequestHandler);
|
||||
MRequest->CookieData = CreateRef<Cookies>();
|
||||
MRequest->SessionData = CreateRef<Session>();
|
||||
Ref<Response> response;
|
||||
|
|
@ -72,7 +117,8 @@ struct RequestJob : public WorkerJob {
|
|||
}
|
||||
};
|
||||
RequestHandler::RequestHandler(const Ref<SocketManager> &manager)
|
||||
: m_SocketManager(manager), m_MiddleWare(CreateRef<MiddleWareHandler>()) {
|
||||
: m_SocketManager(manager),
|
||||
m_MiddleWare(CreateRef<MiddleWareHandler>()) {
|
||||
m_MiddleWare = CreateRef<MiddleWareHandler>();
|
||||
}
|
||||
void RequestHandler::InitThreads(int count) {
|
||||
|
|
@ -89,12 +135,8 @@ void RequestHandler::AddRequest(Ref<Request> &request) {
|
|||
m_Pool.Dispatch(job);
|
||||
}
|
||||
}
|
||||
void RequestHandler::Stop() {
|
||||
m_Pool.Stop();
|
||||
}
|
||||
void RequestHandler::SetRouter(Ref<Router> &router) {
|
||||
m_Router = router;
|
||||
}
|
||||
void RequestHandler::Stop() { m_Pool.Stop(); }
|
||||
void RequestHandler::SetRouter(Ref<Router> &router) { m_Router = router; }
|
||||
void RequestHandler::AddSendResponse(SendData sendData) {
|
||||
auto id = sendData.SocketID;
|
||||
m_Server->m_OutRequest.Add(id, sendData);
|
||||
|
|
@ -103,4 +145,4 @@ void RequestHandler::AddSendResponse(SendData sendData) {
|
|||
m_Server->m_OutRequest.Remove(id);
|
||||
}
|
||||
}
|
||||
} // namespace VWeb
|
||||
} // namespace VWeb
|
||||
|
|
|
|||
|
|
@ -84,4 +84,4 @@ void Route::AllowMethod(HttpMethod method) {
|
|||
if (std::find(m_AllowedMethods.begin(), m_AllowedMethods.end(), method) == m_AllowedMethods.end())
|
||||
m_AllowedMethods.push_back(method);
|
||||
}
|
||||
} // namespace VWeb
|
||||
} // namespace VWeb
|
||||
|
|
|
|||
|
|
@ -157,4 +157,4 @@ void Router::Delete(const std::string &path, RouteFunction func) {
|
|||
if (route)
|
||||
route->DeleteFunc = std::move(func);
|
||||
}
|
||||
} // namespace VWeb
|
||||
} // namespace VWeb
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ static void StringRightTrim(std::string &s) {
|
|||
}
|
||||
|
||||
std::vector<std::string> String::Split(const std::string &s,
|
||||
const std::string &delimiter) {
|
||||
const std::string &delimiter,
|
||||
int limit) {
|
||||
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||
std::string token;
|
||||
std::vector<std::string> res;
|
||||
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos &&
|
||||
(limit == -1 || res.size() < (size_t)limit)) {
|
||||
token = s.substr(pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
res.push_back(token);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ namespace VWeb {
|
|||
class String {
|
||||
public:
|
||||
static std::vector<std::string> Split(const std::string& s,
|
||||
const std::string& delimiter);
|
||||
const std::string& delimiter,
|
||||
int limit = -1);
|
||||
static std::string Join(const std::vector<std::string>& items, const std::string& delimiter);
|
||||
static int ToNumber(std::string& string, int def);
|
||||
static void ToLowerCase(std::string& value);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue