Added Post Body Parsing
This commit is contained in:
parent
afd8f4d999
commit
5c8c4e86b2
14 changed files with 139 additions and 49 deletions
|
@ -17,13 +17,14 @@ set(SOURCE_FILES
|
||||||
Source/StringUtils.cpp
|
Source/StringUtils.cpp
|
||||||
Source/Cookie.cpp
|
Source/Cookie.cpp
|
||||||
Source/Session.cpp
|
Source/Session.cpp
|
||||||
Source/Response.cpp Source/InbuildMiddleWare.cpp)
|
Source/Response.cpp
|
||||||
|
Source/InbuildMiddleWare.cpp)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/)
|
include_directories(${CMAKE_SOURCE_DIR}/)
|
||||||
add_library(VWeb ${SOURCE_FILES})
|
add_library(VWeb ${SOURCE_FILES})
|
||||||
|
|
||||||
set(mode release)
|
set(mode Release)
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
set(mode debug)
|
set(mode Debug)
|
||||||
endif ()
|
endif ()
|
||||||
set(target_file ${CMAKE_SOURCE_DIR}/dist/libVWeb.${mode}.a)
|
set(target_file ${CMAKE_SOURCE_DIR}/dist/libVWeb.${mode}.a)
|
||||||
add_custom_command(TARGET VWeb POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:VWeb> ${target_file})
|
add_custom_command(TARGET VWeb POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:VWeb> ${target_file})
|
||||||
|
|
|
@ -103,5 +103,6 @@ void Cookies::CookieToString(std::stringstream &stream, Cookie &cookie) {
|
||||||
view << "; SameSite=" << sameSiteValue;
|
view << "; SameSite=" << sameSiteValue;
|
||||||
}
|
}
|
||||||
view << "\n";
|
view << "\n";
|
||||||
|
stream << view.str();
|
||||||
}
|
}
|
||||||
} // namespace VWeb
|
} // namespace VWeb
|
|
@ -68,7 +68,7 @@ PreMiddleWareReturn SessionManager::PreHandle(Request &request) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionManager::PostHandle(const Request &request, Response &response) {
|
bool SessionManager::PostHandle(Request &request, Response &response) {
|
||||||
if (response.SessionData->Id.empty() &&
|
if (response.SessionData->Id.empty() &&
|
||||||
response.SessionData->ContainsData()) {
|
response.SessionData->ContainsData()) {
|
||||||
response.SessionData->Update();
|
response.SessionData->Update();
|
||||||
|
@ -80,8 +80,9 @@ bool SessionManager::PostHandle(const Request &request, Response &response) {
|
||||||
}
|
}
|
||||||
m_Sessions[response.SessionData->Id] = response.SessionData;
|
m_Sessions[response.SessionData->Id] = response.SessionData;
|
||||||
auto &sidCookie = response.CookieData->Get("sid");
|
auto &sidCookie = response.CookieData->Get("sid");
|
||||||
|
sidCookie.Name = "sid";
|
||||||
sidCookie.HttpOnly = true;
|
sidCookie.HttpOnly = true;
|
||||||
sidCookie.Secure = true;
|
sidCookie.SameSite = CookieSameSite::Strict;
|
||||||
sidCookie.Value = response.SessionData->Id;
|
sidCookie.Value = response.SessionData->Id;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -101,7 +102,7 @@ void SessionManager::GC() {
|
||||||
#pragma endregion SESSION
|
#pragma endregion SESSION
|
||||||
#pragma region COOKIES
|
#pragma region COOKIES
|
||||||
PreMiddleWareReturn CookieManager::PreHandle(Request &request) {
|
PreMiddleWareReturn CookieManager::PreHandle(Request &request) {
|
||||||
auto &cookieHeaders = request.Header("Cookie");
|
auto &cookieHeaders = request.Header("cookie");
|
||||||
auto &cookies = request.CookieData;
|
auto &cookies = request.CookieData;
|
||||||
if (cookieHeaders.Size() > 0) {
|
if (cookieHeaders.Size() > 0) {
|
||||||
auto &values = cookieHeaders.Values();
|
auto &values = cookieHeaders.Values();
|
||||||
|
@ -118,4 +119,4 @@ PreMiddleWareReturn CookieManager::PreHandle(Request &request) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
#pragma endregion COOKIES
|
#pragma endregion COOKIES
|
||||||
} // namespace VWeb
|
} // namespace VWeb
|
||||||
|
|
|
@ -27,6 +27,7 @@ bool ParseRequest(Ref<Request> &request) {
|
||||||
if (index != std::string::npos) {
|
if (index != std::string::npos) {
|
||||||
auto key = line.substr(0, index);
|
auto key = line.substr(0, index);
|
||||||
String::Trim(key);
|
String::Trim(key);
|
||||||
|
String::ToLowerCase(key);
|
||||||
request->Header(key).Add(String::TrimCopy(line.substr(index + 1)));
|
request->Header(key).Add(String::TrimCopy(line.substr(index + 1)));
|
||||||
} else if (line.find("HTTP")) {
|
} else if (line.find("HTTP")) {
|
||||||
auto headers = String::Split(line, " ");
|
auto headers = String::Split(line, " ");
|
||||||
|
@ -41,6 +42,49 @@ bool ParseRequest(Ref<Request> &request) {
|
||||||
return true;
|
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 {
|
struct RequestJob : public WorkerJob {
|
||||||
Ref<Request> MRequest{};
|
Ref<Request> MRequest{};
|
||||||
Ref<Router> MRouter{};
|
Ref<Router> MRouter{};
|
||||||
|
@ -53,6 +97,7 @@ struct RequestJob : public WorkerJob {
|
||||||
SocketUtils::Close(MRequest->ID);
|
SocketUtils::Close(MRequest->ID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ParseParameters(*MRequest, *MRequestHandler);
|
||||||
MRequest->CookieData = CreateRef<Cookies>();
|
MRequest->CookieData = CreateRef<Cookies>();
|
||||||
MRequest->SessionData = CreateRef<Session>();
|
MRequest->SessionData = CreateRef<Session>();
|
||||||
Ref<Response> response;
|
Ref<Response> response;
|
||||||
|
@ -72,7 +117,8 @@ struct RequestJob : public WorkerJob {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
RequestHandler::RequestHandler(const Ref<SocketManager> &manager)
|
RequestHandler::RequestHandler(const Ref<SocketManager> &manager)
|
||||||
: m_SocketManager(manager), m_MiddleWare(CreateRef<MiddleWareHandler>()) {
|
: m_SocketManager(manager),
|
||||||
|
m_MiddleWare(CreateRef<MiddleWareHandler>()) {
|
||||||
m_MiddleWare = CreateRef<MiddleWareHandler>();
|
m_MiddleWare = CreateRef<MiddleWareHandler>();
|
||||||
}
|
}
|
||||||
void RequestHandler::InitThreads(int count) {
|
void RequestHandler::InitThreads(int count) {
|
||||||
|
@ -89,12 +135,8 @@ void RequestHandler::AddRequest(Ref<Request> &request) {
|
||||||
m_Pool.Dispatch(job);
|
m_Pool.Dispatch(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void RequestHandler::Stop() {
|
void RequestHandler::Stop() { m_Pool.Stop(); }
|
||||||
m_Pool.Stop();
|
void RequestHandler::SetRouter(Ref<Router> &router) { m_Router = router; }
|
||||||
}
|
|
||||||
void RequestHandler::SetRouter(Ref<Router> &router) {
|
|
||||||
m_Router = router;
|
|
||||||
}
|
|
||||||
void RequestHandler::AddSendResponse(SendData sendData) {
|
void RequestHandler::AddSendResponse(SendData sendData) {
|
||||||
auto id = sendData.SocketID;
|
auto id = sendData.SocketID;
|
||||||
m_Server->m_OutRequest.Add(id, sendData);
|
m_Server->m_OutRequest.Add(id, sendData);
|
||||||
|
@ -103,4 +145,4 @@ void RequestHandler::AddSendResponse(SendData sendData) {
|
||||||
m_Server->m_OutRequest.Remove(id);
|
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())
|
if (std::find(m_AllowedMethods.begin(), m_AllowedMethods.end(), method) == m_AllowedMethods.end())
|
||||||
m_AllowedMethods.push_back(method);
|
m_AllowedMethods.push_back(method);
|
||||||
}
|
}
|
||||||
} // namespace VWeb
|
} // namespace VWeb
|
||||||
|
|
|
@ -157,4 +157,4 @@ void Router::Delete(const std::string &path, RouteFunction func) {
|
||||||
if (route)
|
if (route)
|
||||||
route->DeleteFunc = std::move(func);
|
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,
|
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();
|
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||||
std::string token;
|
std::string token;
|
||||||
std::vector<std::string> res;
|
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);
|
token = s.substr(pos_start, pos_end - pos_start);
|
||||||
pos_start = pos_end + delim_len;
|
pos_start = pos_end + delim_len;
|
||||||
res.push_back(token);
|
res.push_back(token);
|
||||||
|
|
|
@ -7,7 +7,8 @@ namespace VWeb {
|
||||||
class String {
|
class String {
|
||||||
public:
|
public:
|
||||||
static std::vector<std::string> Split(const std::string& s,
|
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 std::string Join(const std::vector<std::string>& items, const std::string& delimiter);
|
||||||
static int ToNumber(std::string& string, int def);
|
static int ToNumber(std::string& string, int def);
|
||||||
static void ToLowerCase(std::string& value);
|
static void ToLowerCase(std::string& value);
|
||||||
|
|
85
VWeb.h
85
VWeb.h
|
@ -3,6 +3,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -275,7 +276,8 @@ public:
|
||||||
void AddRoute(const std::string &path, const Ref<Route> &route);
|
void AddRoute(const std::string &path, const Ref<Route> &route);
|
||||||
void RemoveRoute(const std::string &path);
|
void RemoveRoute(const std::string &path);
|
||||||
|
|
||||||
Ref<MiddleWareHandler>& Middleware();
|
Ref<MiddleWareHandler> &Middleware();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Execute();
|
void Execute();
|
||||||
void OutgoingExecute(epoll_event &event);
|
void OutgoingExecute(epoll_event &event);
|
||||||
|
@ -300,6 +302,7 @@ protected:
|
||||||
using ms = std::chrono::duration<double, std::milli>;
|
using ms = std::chrono::duration<double, std::milli>;
|
||||||
struct SessionData {
|
struct SessionData {
|
||||||
virtual ~SessionData() = default;
|
virtual ~SessionData() = default;
|
||||||
|
template <class T> T *As() { return reinterpret_cast<T *>(this); }
|
||||||
};
|
};
|
||||||
struct Session {
|
struct Session {
|
||||||
std::string Id;
|
std::string Id;
|
||||||
|
@ -309,7 +312,9 @@ struct Session {
|
||||||
void Remove(const std::string &key);
|
void Remove(const std::string &key);
|
||||||
bool Has(const std::string &key);
|
bool Has(const std::string &key);
|
||||||
Ref<SessionData> &operator[](const std::string &key) { return m_Data[key]; }
|
Ref<SessionData> &operator[](const std::string &key) { return m_Data[key]; }
|
||||||
void SetSessionData(const std::string& key, const Ref<SessionData>& data) { m_Data[key] = data; }
|
void SetSessionData(const std::string &key, const Ref<SessionData> &data) {
|
||||||
|
m_Data[key] = data;
|
||||||
|
}
|
||||||
bool ContainsData() { return !m_Data.empty(); }
|
bool ContainsData() { return !m_Data.empty(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -391,15 +396,15 @@ enum class HttpMethod {
|
||||||
};
|
};
|
||||||
enum class CookieSameSite { Invalid = 0, Strict, Lax, None };
|
enum class CookieSameSite { Invalid = 0, Strict, Lax, None };
|
||||||
struct Cookie {
|
struct Cookie {
|
||||||
std::string Name;
|
std::string Name{};
|
||||||
std::string Value;
|
std::string Value{};
|
||||||
std::string Expires;
|
std::string Expires{};
|
||||||
int MaxAge{};
|
int MaxAge{};
|
||||||
std::string Domain;
|
std::string Domain{};
|
||||||
std::string Path;
|
std::string Path{"/"};
|
||||||
bool Secure{};
|
bool Secure{};
|
||||||
bool HttpOnly{};
|
bool HttpOnly{};
|
||||||
CookieSameSite SameSite{CookieSameSite::Invalid};
|
CookieSameSite SameSite{CookieSameSite::Strict};
|
||||||
bool IsOld = false;
|
bool IsOld = false;
|
||||||
};
|
};
|
||||||
struct Cookies {
|
struct Cookies {
|
||||||
|
@ -442,9 +447,13 @@ public:
|
||||||
Ref<Cookies> CookieData;
|
Ref<Cookies> CookieData;
|
||||||
Cookie &GetCookie(const std::string &key) { return CookieData->Get(key); };
|
Cookie &GetCookie(const std::string &key) { return CookieData->Get(key); };
|
||||||
ParameterValue &Parameter(const std::string &key) { return Parameters[key]; }
|
ParameterValue &Parameter(const std::string &key) { return Parameters[key]; }
|
||||||
bool HasParameter(const std::string &key) const { return Parameters.contains(key); }
|
bool HasParameter(const std::string &key) const {
|
||||||
|
return Parameters.contains(key);
|
||||||
|
}
|
||||||
bool HasHeader(const std::string &key) const { return Headers.contains(key); }
|
bool HasHeader(const std::string &key) const { return Headers.contains(key); }
|
||||||
std::string &FirstOf(const std::string &key) { return Parameters[key].GetFirst(); }
|
std::string &FirstOf(const std::string &key) {
|
||||||
|
return Parameters[key].GetFirst();
|
||||||
|
}
|
||||||
ParameterValue &Header(const std::string &key) { return Headers[key]; }
|
ParameterValue &Header(const std::string &key) { return Headers[key]; }
|
||||||
std::unordered_map<std::string, ParameterValue> Parameters;
|
std::unordered_map<std::string, ParameterValue> Parameters;
|
||||||
std::unordered_map<std::string, ParameterValue> Headers;
|
std::unordered_map<std::string, ParameterValue> Headers;
|
||||||
|
@ -483,6 +492,7 @@ protected:
|
||||||
std::unordered_map<std::string, ParameterValue> m_Headers;
|
std::unordered_map<std::string, ParameterValue> m_Headers;
|
||||||
};
|
};
|
||||||
class MiddleWareHandler;
|
class MiddleWareHandler;
|
||||||
|
typedef std::function<const void(Request &, const std::string& body)> ParseFunction;
|
||||||
class RequestHandler {
|
class RequestHandler {
|
||||||
public:
|
public:
|
||||||
explicit RequestHandler(const Ref<SocketManager> &manager);
|
explicit RequestHandler(const Ref<SocketManager> &manager);
|
||||||
|
@ -492,8 +502,15 @@ public:
|
||||||
void SetRouter(Ref<Router> &router);
|
void SetRouter(Ref<Router> &router);
|
||||||
void AddSendResponse(SendData);
|
void AddSendResponse(SendData);
|
||||||
Ref<MiddleWareHandler> &Middleware() { return m_MiddleWare; }
|
Ref<MiddleWareHandler> &Middleware() { return m_MiddleWare; }
|
||||||
|
bool HasBodyParser(const std::string &key) {
|
||||||
|
return m_ParseFunctions.contains(key);
|
||||||
|
}
|
||||||
|
ParseFunction &GetBodyParser(const std::string &key) {
|
||||||
|
return m_ParseFunctions.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::unordered_map<std::string, ParseFunction> m_ParseFunctions;
|
||||||
Ref<Router> m_Router{nullptr};
|
Ref<Router> m_Router{nullptr};
|
||||||
Ref<SocketManager> m_SocketManager{nullptr};
|
Ref<SocketManager> m_SocketManager{nullptr};
|
||||||
Server *m_Server{nullptr};
|
Server *m_Server{nullptr};
|
||||||
|
@ -503,7 +520,7 @@ protected:
|
||||||
friend Server;
|
friend Server;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<bool(Request&,Response&)> RouteFunction;
|
typedef std::function<bool(Request &, Response &)> RouteFunction;
|
||||||
class Route {
|
class Route {
|
||||||
public:
|
public:
|
||||||
Route() = default;
|
Route() = default;
|
||||||
|
@ -540,20 +557,20 @@ public:
|
||||||
static void AddToArgs(Ref<Request> &request, Vector<std::string> &items);
|
static void AddToArgs(Ref<Request> &request, Vector<std::string> &items);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Get(const std::string& path, RouteFunction);
|
void Get(const std::string &path, RouteFunction);
|
||||||
void Post(const std::string& path, RouteFunction);
|
void Post(const std::string &path, RouteFunction);
|
||||||
void Put(const std::string& path, RouteFunction);
|
void Put(const std::string &path, RouteFunction);
|
||||||
void Patch(const std::string& path, RouteFunction);
|
void Patch(const std::string &path, RouteFunction);
|
||||||
void Delete(const std::string& path, RouteFunction);
|
void Delete(const std::string &path, RouteFunction);
|
||||||
std::unordered_map<std::string, Ref<Route>> m_Routes;
|
std::unordered_map<std::string, Ref<Route>> m_Routes;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::optional<Ref<Response>> PreMiddleWareReturn;
|
typedef std::optional<Ref<Response>> PreMiddleWareReturn;
|
||||||
struct MiddleWare {
|
struct MiddleWare {
|
||||||
int Pos{0};
|
int Pos{0};
|
||||||
virtual PreMiddleWareReturn PreHandle(Request &){ return {}; }
|
virtual PreMiddleWareReturn PreHandle(Request &) { return {}; }
|
||||||
virtual bool PostHandle(const Request &, Response &){ return true; }
|
virtual bool PostHandle(Request &, Response &) { return true; }
|
||||||
virtual void Shutdown(const Request &, const Response &){};
|
virtual void Shutdown(Request &, const Response &){};
|
||||||
bool operator<(const MiddleWare *rhs) const { return Pos < rhs->Pos; }
|
bool operator<(const MiddleWare *rhs) const { return Pos < rhs->Pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -564,17 +581,22 @@ public:
|
||||||
void Shutdown(Ref<Request> &, Ref<Response> &);
|
void Shutdown(Ref<Request> &, Ref<Response> &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class T> Ref<MiddleWare> GetRef() { return GetById(typeid(T).name()); }
|
template <class T> Ref<MiddleWare> GetRef() {
|
||||||
template <class T> T& Get() { return static_cast<T&>(*GetById(typeid(T).name())); }
|
return GetById(typeid(T).name());
|
||||||
|
}
|
||||||
|
template <class T> T &Get() {
|
||||||
|
return static_cast<T &>(*GetById(typeid(T).name()));
|
||||||
|
}
|
||||||
template <class T> void Set(Ref<MiddleWare> &instance) {
|
template <class T> void Set(Ref<MiddleWare> &instance) {
|
||||||
auto &type = typeid(T);
|
auto &type = typeid(T);
|
||||||
if (type.before(typeid(MiddleWare)))
|
if (type.before(typeid(MiddleWare)))
|
||||||
SetById(type.name(), instance);
|
SetById(type.name(), instance);
|
||||||
}
|
}
|
||||||
template <class T> T& Create() {
|
template <class T> T &Create() {
|
||||||
return static_cast<T&>(*CreateMiddleWare<T>());
|
return static_cast<T &>(*CreateMiddleWare<T>());
|
||||||
}
|
}
|
||||||
template <class T> void Remove() { RemoveById(typeid(T).name()); }
|
template <class T> void Remove() { RemoveById(typeid(T).name()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <class T> Ref<MiddleWare> CreateMiddleWare() {
|
template <class T> Ref<MiddleWare> CreateMiddleWare() {
|
||||||
return SetById(typeid(T).name(), CreateRef<T>());
|
return SetById(typeid(T).name(), CreateRef<T>());
|
||||||
|
@ -585,13 +607,16 @@ protected:
|
||||||
std::map<std::string, Ref<MiddleWare>> m_MiddleWares;
|
std::map<std::string, Ref<MiddleWare>> m_MiddleWares;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<PreMiddleWareReturn(Request& req)> AuthFunction;
|
typedef std::function<PreMiddleWareReturn(Request &req)> AuthFunction;
|
||||||
class AuthWare : public MiddleWare {
|
class AuthWare : public MiddleWare {
|
||||||
public:
|
public:
|
||||||
AuthWare() = default;
|
AuthWare() = default;
|
||||||
~AuthWare() = default;
|
~AuthWare() = default;
|
||||||
PreMiddleWareReturn PreHandle(Request &request) override;
|
PreMiddleWareReturn PreHandle(Request &request) override;
|
||||||
void SetAuthMethod(AuthFunction function) { m_AuthFunction = std::move(function); }
|
void SetAuthMethod(AuthFunction function) {
|
||||||
|
m_AuthFunction = std::move(function);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AuthFunction m_AuthFunction{nullptr};
|
AuthFunction m_AuthFunction{nullptr};
|
||||||
};
|
};
|
||||||
|
@ -600,10 +625,12 @@ class SessionManager : public MiddleWare {
|
||||||
public:
|
public:
|
||||||
SessionManager();
|
SessionManager();
|
||||||
~SessionManager();
|
~SessionManager();
|
||||||
PreMiddleWareReturn PreHandle(Request& request) override;
|
PreMiddleWareReturn PreHandle(Request &request) override;
|
||||||
bool PostHandle(const Request& request, Response& response) override;
|
bool PostHandle(Request &request, Response &response) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GC();
|
void GC();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Ref<std::thread> m_GCThread;
|
Ref<std::thread> m_GCThread;
|
||||||
std::mutex m_Mutex;
|
std::mutex m_Mutex;
|
||||||
|
@ -616,9 +643,9 @@ class CookieManager : public MiddleWare {
|
||||||
public:
|
public:
|
||||||
CookieManager() = default;
|
CookieManager() = default;
|
||||||
~CookieManager() = default;
|
~CookieManager() = default;
|
||||||
PreMiddleWareReturn PreHandle(Request&) override;
|
PreMiddleWareReturn PreHandle(Request &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma endregion VWEB_ROUTING
|
#pragma endregion VWEB_ROUTING
|
||||||
#pragma endregion VWEB
|
#pragma endregion VWEB
|
||||||
} // namespace VWeb
|
} // namespace VWeb
|
BIN
dist/libVWeb.Debug.a
vendored
Normal file
BIN
dist/libVWeb.Debug.a
vendored
Normal file
Binary file not shown.
BIN
dist/libVWeb.Release.a
vendored
Normal file
BIN
dist/libVWeb.Release.a
vendored
Normal file
Binary file not shown.
BIN
dist/libVWeb.debug.a
vendored
BIN
dist/libVWeb.debug.a
vendored
Binary file not shown.
BIN
dist/libVWeb.release.a
vendored
BIN
dist/libVWeb.release.a
vendored
Binary file not shown.
|
@ -1,5 +1,20 @@
|
||||||
#include <VWeb.h>
|
#include <VWeb.h>
|
||||||
|
|
||||||
|
class MyCompleteController : public VWeb::Route {
|
||||||
|
public:
|
||||||
|
bool Get(const VWeb::Request&, VWeb::Response& response) {
|
||||||
|
response << "MyCompleteController: GET";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Post(const VWeb::Request&, VWeb::Response& response) {
|
||||||
|
response << "MyCompleteController: POST";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsAllowed(const VWeb::Request& request) {
|
||||||
|
return request.HasHeader("Auth");
|
||||||
|
}
|
||||||
|
};
|
||||||
bool Ping(const VWeb::Request&, VWeb::Response& response) {
|
bool Ping(const VWeb::Request&, VWeb::Response& response) {
|
||||||
response << "Pong";
|
response << "Pong";
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue