Change Variable names and all to snake case
This commit is contained in:
4
http.hpp
4
http.hpp
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
namespace http {
|
namespace http {
|
||||||
class statuscode {
|
class StatusCode {
|
||||||
public:
|
public:
|
||||||
enum statusCode {
|
enum statusCode {
|
||||||
CONTINUE = 100,
|
CONTINUE = 100,
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
HTTP_VERSION_NOT_SUPPORTED = 505
|
HTTP_VERSION_NOT_SUPPORTED = 505
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static std::string StatusCodeString(const statusCode code) {
|
constexpr static std::string status_code_string(const statusCode code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case CONTINUE:
|
case CONTINUE:
|
||||||
return "Continue";
|
return "Continue";
|
||||||
|
|||||||
38
main.cpp
38
main.cpp
@@ -4,40 +4,40 @@
|
|||||||
using namespace http;
|
using namespace http;
|
||||||
|
|
||||||
void HelloWorld(Request req, Response *res) {
|
void HelloWorld(Request req, Response *res) {
|
||||||
res->SetPayload("Hello World!");
|
res->set_payload("Hello World!");
|
||||||
res->SetContentType("text/plain");
|
res->set_content_type("text/plain");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Router router(8181);
|
Router router(8181);
|
||||||
|
|
||||||
// Allow all Methods
|
// Allow all Methods
|
||||||
router.Handle("GET /helloWorld", HelloWorld);
|
router.handle("GET /helloWorld", HelloWorld);
|
||||||
router.Handle("GET /healthz", [](Request req, Response *res) {
|
router.handle("GET /healthz", [](Request req, Response *res) {
|
||||||
res->SetStatusCode(statuscode::OK);
|
res->set_status_code(StatusCode::OK);
|
||||||
res->SetPayload(std::vector<std::byte>());
|
res->set_payload(std::vector<std::byte>());
|
||||||
res->SetContentType("text/plain");
|
res->set_content_type("text/plain");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only allow GET
|
// Only allow GET
|
||||||
router.Handle("GET /echo/{name}", [](Request req, Response *res) {
|
router.handle("GET /echo/{name}", [](Request req, Response *res) {
|
||||||
std::string name = req.path.Get("name").value_or("No Name given");
|
std::string name = req.path.get("name").value_or("No Name given");
|
||||||
res->SetPayload("Hello " + name);
|
res->set_payload("Hello " + name);
|
||||||
res->SetContentType("text/plain");
|
res->set_content_type("text/plain");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only allow POST
|
// Only allow POST
|
||||||
router.Handle("POST /echo/{name}", [](Request req, Response *res) {
|
router.handle("POST /echo/{name}", [](Request req, Response *res) {
|
||||||
std::string name = req.path.Get("name").value_or("No Name given");
|
std::string name = req.path.get("name").value_or("No Name given");
|
||||||
res->SetPayload("Hello with Post" + name);
|
res->set_payload("Hello with Post" + name);
|
||||||
res->SetContentType("text/plain");
|
res->set_content_type("text/plain");
|
||||||
});
|
});
|
||||||
|
|
||||||
router.Handle("GET /", [](Request req, Response *res) {
|
router.handle("GET /", [](Request req, Response *res) {
|
||||||
res->SetPayload("Main");
|
res->set_payload("Main");
|
||||||
res->SetContentType("text/plain");
|
res->set_content_type("text/plain");
|
||||||
});
|
});
|
||||||
|
|
||||||
router.Start();
|
router.start();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
8
path.cpp
8
path.cpp
@@ -10,16 +10,16 @@ Path::Path(std::string path) {
|
|||||||
m_query = path;
|
m_query = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Path::Get(std::string name) {
|
std::optional<std::string> Path::get(std::string name) {
|
||||||
if (m_variables.contains(name))
|
if (m_variables.contains(name))
|
||||||
return m_variables.at(name);
|
return m_variables.at(name);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Path::Base() { return m_base; }
|
std::string Path::base() { return m_base; }
|
||||||
std::string Path::Query() { return m_query; }
|
std::string Path::query() { return m_query; }
|
||||||
|
|
||||||
void Path::Match(std::string pattern) {
|
void Path::match(std::string pattern) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
std::string path = m_base;
|
std::string path = m_base;
|
||||||
while (pos != -1) {
|
while (pos != -1) {
|
||||||
|
|||||||
8
path.hpp
8
path.hpp
@@ -15,10 +15,10 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Path(std::string path);
|
Path(std::string path);
|
||||||
std::optional<std::string> Get(std::string name);
|
std::optional<std::string> get(std::string name);
|
||||||
std::string Query();
|
std::string query();
|
||||||
std::string Base();
|
std::string base();
|
||||||
void Match(std::string pattern);
|
void match(std::string pattern);
|
||||||
};
|
};
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
|||||||
12
request.hpp
12
request.hpp
@@ -12,20 +12,20 @@ class Request {
|
|||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> m_headers;
|
std::map<std::string, std::string> m_headers;
|
||||||
std::string m_method;
|
std::string m_method;
|
||||||
std::string m_pathRaw;
|
std::string m_path_raw;
|
||||||
std::vector<std::byte> m_payload;
|
std::vector<std::byte> m_payload;
|
||||||
std::string m_protocol;
|
std::string m_protocol;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool protocol(std::stringstream *ss, int *procPart, char c);
|
bool protocol(std::stringstream *ss, int *proc_part, char c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Path path;
|
Path path;
|
||||||
explicit Request(std::vector<std::byte> buf);
|
explicit Request(std::vector<std::byte> buf);
|
||||||
void Print();
|
void print();
|
||||||
bool HasData();
|
bool has_data();
|
||||||
std::string Method();
|
std::string method();
|
||||||
std::vector<std::byte> Data();
|
std::vector<std::byte> data();
|
||||||
};
|
};
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
|||||||
20
response.hpp
20
response.hpp
@@ -11,19 +11,17 @@ class Response {
|
|||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> m_headers;
|
std::map<std::string, std::string> m_headers;
|
||||||
std::vector<std::byte> m_payload;
|
std::vector<std::byte> m_payload;
|
||||||
statuscode::statusCode m_statusCode;
|
StatusCode::statusCode m_statusCode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Response(statuscode::statusCode statusCode);
|
Response(StatusCode::statusCode status_code);
|
||||||
// Response(std::vector<std::byte> data);
|
void set_header(const std::string name, const std::string value);
|
||||||
// Response(std::string data);
|
void set_payload(const std::vector<std::byte> data);
|
||||||
void SetHeader(const std::string name, const std::string value);
|
void set_payload(const std::string data);
|
||||||
void SetPayload(const std::vector<std::byte> data);
|
void set_content_type(const std::string type);
|
||||||
void SetPayload(const std::string data);
|
void set_status_code(const StatusCode::statusCode status_code);
|
||||||
void SetContentType(const std::string type);
|
void send(int client_socket);
|
||||||
void SetStatusCode(const statuscode::statusCode statuscode);
|
void print();
|
||||||
void Send(int clientSocket);
|
|
||||||
void Print();
|
|
||||||
};
|
};
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
|||||||
38
router.cpp
38
router.cpp
@@ -20,12 +20,12 @@ Router::Router(int port) {
|
|||||||
m_address.sin_addr.s_addr = INADDR_ANY;
|
m_address.sin_addr.s_addr = INADDR_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Router::Start() {
|
int Router::start() {
|
||||||
int err = bind(m_socket, (struct sockaddr *)&m_address, sizeof(m_address));
|
int err = bind(m_socket, (struct sockaddr *)&m_address, sizeof(m_address));
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
StartThreadLoop();
|
start_thread_loop();
|
||||||
|
|
||||||
err = listen(m_socket, 5);
|
err = listen(m_socket, 5);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
@@ -33,13 +33,13 @@ int Router::Start() {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int client = accept(m_socket, nullptr, nullptr);
|
int client = accept(m_socket, nullptr, nullptr);
|
||||||
QueueClient(client);
|
queue_client(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
StopThreadLoop();
|
stop_thread_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::QueueClient(int fd) {
|
void Router::queue_client(int fd) {
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_clients.push(fd);
|
m_clients.push(fd);
|
||||||
@@ -47,17 +47,17 @@ void Router::QueueClient(int fd) {
|
|||||||
m_cond.notify_one();
|
m_cond.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::StartThreadLoop() {
|
void Router::start_thread_loop() {
|
||||||
const uint32_t numThreads = std::thread::hardware_concurrency();
|
const uint32_t numThreads = std::thread::hardware_concurrency();
|
||||||
for (uint32_t i = 0; i < numThreads; ++i) {
|
for (uint32_t i = 0; i < numThreads; ++i) {
|
||||||
m_threads.emplace_back(std::thread(&Router::ThreadLoop, this));
|
m_threads.emplace_back(std::thread(&Router::thread_loop, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::StopThreadLoop() {
|
void Router::stop_thread_loop() {
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_shouldTerminate = true;
|
m_should_terminate = true;
|
||||||
}
|
}
|
||||||
m_cond.notify_all();
|
m_cond.notify_all();
|
||||||
for (std::thread &active_thread : m_threads) {
|
for (std::thread &active_thread : m_threads) {
|
||||||
@@ -66,15 +66,15 @@ void Router::StopThreadLoop() {
|
|||||||
m_threads.clear();
|
m_threads.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::ThreadLoop() {
|
void Router::thread_loop() {
|
||||||
std::vector<std::byte> buffer(1024);
|
std::vector<std::byte> buffer(1024);
|
||||||
while (true) {
|
while (true) {
|
||||||
int client;
|
int client;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_cond.wait(lock,
|
m_cond.wait(lock,
|
||||||
[this] { return !m_clients.empty() || m_shouldTerminate; });
|
[this] { return !m_clients.empty() || m_should_terminate; });
|
||||||
if (m_shouldTerminate)
|
if (m_should_terminate)
|
||||||
return;
|
return;
|
||||||
client = m_clients.front();
|
client = m_clients.front();
|
||||||
m_clients.pop();
|
m_clients.pop();
|
||||||
@@ -83,7 +83,7 @@ void Router::ThreadLoop() {
|
|||||||
recv(client, buffer.data(), buffer.size(), 0);
|
recv(client, buffer.data(), buffer.size(), 0);
|
||||||
Request req(buffer);
|
Request req(buffer);
|
||||||
Response res = Route(req);
|
Response res = Route(req);
|
||||||
res.Send(client);
|
res.send(client);
|
||||||
|
|
||||||
shutdown(client, SHUT_WR);
|
shutdown(client, SHUT_WR);
|
||||||
while (recv(client, buffer.data(), buffer.size(), 0) > 0) {
|
while (recv(client, buffer.data(), buffer.size(), 0) > 0) {
|
||||||
@@ -93,7 +93,7 @@ void Router::ThreadLoop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::Handle(std::string pathPattern,
|
void Router::handle(std::string pathPattern,
|
||||||
std::function<void(Request, Response *)> func) {
|
std::function<void(Request, Response *)> func) {
|
||||||
auto route = split(pathPattern, " ");
|
auto route = split(pathPattern, " ");
|
||||||
// TODO: UNSAFE CHECK BOUNDS
|
// TODO: UNSAFE CHECK BOUNDS
|
||||||
@@ -102,18 +102,18 @@ void Router::Handle(std::string pathPattern,
|
|||||||
tree = std::make_shared<Tree>(Tree(route[0]));
|
tree = std::make_shared<Tree>(Tree(route[0]));
|
||||||
m_routes.insert_or_assign(route[0], tree);
|
m_routes.insert_or_assign(route[0], tree);
|
||||||
}
|
}
|
||||||
tree->AddPath(route[1], func);
|
tree->add_path(route[1], func);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response Router::Route(Request req) {
|
Response Router::Route(Request req) {
|
||||||
auto tree = m_routes[req.Method()];
|
auto tree = m_routes[req.method()];
|
||||||
auto route = tree->Get(req.path.Base());
|
auto route = tree->get(req.path.base());
|
||||||
|
|
||||||
if (!route.has_value()) {
|
if (!route.has_value()) {
|
||||||
return Response(statuscode::NOT_FOUND);
|
return Response(StatusCode::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response res(statuscode::OK);
|
Response res(StatusCode::OK);
|
||||||
route.value()(req, &res);
|
route.value()(req, &res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
16
router.hpp
16
router.hpp
@@ -25,18 +25,18 @@ private:
|
|||||||
std::condition_variable m_cond;
|
std::condition_variable m_cond;
|
||||||
std::vector<std::thread> m_threads;
|
std::vector<std::thread> m_threads;
|
||||||
std::queue<int> m_clients;
|
std::queue<int> m_clients;
|
||||||
bool m_shouldTerminate = false;
|
bool m_should_terminate = false;
|
||||||
void StartThreadLoop();
|
void start_thread_loop();
|
||||||
void ThreadLoop();
|
void thread_loop();
|
||||||
void QueueClient(int client);
|
void queue_client(int client);
|
||||||
void StopThreadLoop();
|
void stop_thread_loop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Router(int port);
|
Router(int port);
|
||||||
void Handle(std::string pathPattern,
|
void handle(std::string path_pattern,
|
||||||
std::function<void(Request, Response *)> func);
|
std::function<void(Request, Response *)> func);
|
||||||
int Start();
|
int start();
|
||||||
int Stop();
|
int stop();
|
||||||
};
|
};
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
|||||||
28
tree.cpp
28
tree.cpp
@@ -9,18 +9,18 @@
|
|||||||
using namespace http;
|
using namespace http;
|
||||||
|
|
||||||
Node::Node(std::string sub) {
|
Node::Node(std::string sub) {
|
||||||
m_subPath = sub;
|
m_sub_path = sub;
|
||||||
m_isDummy = true;
|
m_is_dummy = true;
|
||||||
m_isValue = false;
|
m_is_value = false;
|
||||||
m_function = nullptr;
|
m_function = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::Node(std::string sub, bool isValue,
|
Node::Node(std::string sub, bool isValue,
|
||||||
std::function<void(Request, Response *)> func) {
|
std::function<void(Request, Response *)> func) {
|
||||||
m_subPath = sub;
|
m_sub_path = sub;
|
||||||
m_isValue = isValue;
|
m_is_value = isValue;
|
||||||
m_function = func;
|
m_function = func;
|
||||||
m_isDummy = false;
|
m_is_dummy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree::Tree(std::string method) { m_method = method; }
|
Tree::Tree(std::string method) { m_method = method; }
|
||||||
@@ -31,7 +31,7 @@ void addNode(std::shared_ptr<Node> const &parent, std::string path,
|
|||||||
std::shared_ptr<Node> curr = parent->m_next[path];
|
std::shared_ptr<Node> curr = parent->m_next[path];
|
||||||
if (rest.size() == 0) {
|
if (rest.size() == 0) {
|
||||||
if (curr) {
|
if (curr) {
|
||||||
curr->m_isDummy = false;
|
curr->m_is_dummy = false;
|
||||||
curr->m_function = func;
|
curr->m_function = func;
|
||||||
} else {
|
} else {
|
||||||
std::shared_ptr<Node> leaf =
|
std::shared_ptr<Node> leaf =
|
||||||
@@ -55,7 +55,7 @@ void addNode(std::shared_ptr<Node> const &parent, std::string path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tree::AddPath(std::string path,
|
void Tree::add_path(std::string path,
|
||||||
std::function<void(Request, Response *)> func) {
|
std::function<void(Request, Response *)> func) {
|
||||||
auto subPaths = split(path, "/");
|
auto subPaths = split(path, "/");
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@ void printNode(std::shared_ptr<Node> node, size_t depth, size_t max_depth) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::string(depth, ' ') << "sub: \"" << node->m_subPath
|
std::cout << std::string(depth, ' ') << "sub: \"" << node->m_sub_path
|
||||||
<< "\" IsDummy: " << node->m_isDummy << std::endl;
|
<< "\" IsDummy: " << node->m_is_dummy << std::endl;
|
||||||
for (auto &next : node->m_next) {
|
for (auto &next : node->m_next) {
|
||||||
printNode(next.second, depth + 1, max_depth);
|
printNode(next.second, depth + 1, max_depth);
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ traverse(std::shared_ptr<Node> const &parent, std::string path,
|
|||||||
|
|
||||||
std::shared_ptr<Node> curr = parent->m_next[path];
|
std::shared_ptr<Node> curr = parent->m_next[path];
|
||||||
if (rest.size() == 0) {
|
if (rest.size() == 0) {
|
||||||
if (curr != nullptr && !curr->m_isDummy)
|
if (curr != nullptr && !curr->m_is_dummy)
|
||||||
return curr->m_function;
|
return curr->m_function;
|
||||||
else
|
else
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -109,10 +109,10 @@ traverse(std::shared_ptr<Node> const &parent, std::string path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::function<void(Request, Response *)>>
|
std::optional<std::function<void(Request, Response *)>>
|
||||||
Tree::Get(std::string path) {
|
Tree::get(std::string path) {
|
||||||
auto subs = split(path, "/");
|
auto subs = split(path, "/");
|
||||||
if (subs.size() == 0) {
|
if (subs.size() == 0) {
|
||||||
if (!m_root->m_isDummy)
|
if (!m_root->m_is_dummy)
|
||||||
return m_root->m_function;
|
return m_root->m_function;
|
||||||
else
|
else
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -123,4 +123,4 @@ Tree::Get(std::string path) {
|
|||||||
return traverse(m_root, newPath, subs);
|
return traverse(m_root, newPath, subs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tree::DebugPrint() { printNode(m_root, 0, 10); }
|
void Tree::debug_Print() { printNode(m_root, 0, 10); }
|
||||||
|
|||||||
12
tree.hpp
12
tree.hpp
@@ -11,9 +11,9 @@ namespace http {
|
|||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
bool m_isValue;
|
bool m_is_value;
|
||||||
bool m_isDummy;
|
bool m_is_dummy;
|
||||||
std::string m_subPath;
|
std::string m_sub_path;
|
||||||
std::map<std::string, std::shared_ptr<Node>> m_next;
|
std::map<std::string, std::shared_ptr<Node>> m_next;
|
||||||
std::function<void(Request, Response *)> m_function;
|
std::function<void(Request, Response *)> m_function;
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Tree(std::string method);
|
Tree(std::string method);
|
||||||
void AddPath(std::string, std::function<void(Request, Response *)>);
|
void add_path(std::string, std::function<void(Request, Response *)>);
|
||||||
std::optional<std::function<void(Request, Response *)>> Get(std::string);
|
std::optional<std::function<void(Request, Response *)>> get(std::string);
|
||||||
void DebugPrint();
|
void debug_Print();
|
||||||
};
|
};
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user