Replace shared_pointer with RAII, also fix root path not routing correctly
This commit is contained in:
1
Makefile
1
Makefile
@@ -26,7 +26,6 @@ build: all
|
|||||||
g++ -std=c++20 -o server main.cpp -L. -lhttpablu
|
g++ -std=c++20 -o server main.cpp -L. -lhttpablu
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
g++ -std=c++20 -o server main.cpp -L. -lhttpablu
|
|
||||||
./server
|
./server
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
@@ -21,6 +20,12 @@ Router::Router(int port) {
|
|||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Router::~Router() {
|
||||||
|
for (auto t : m_routes) {
|
||||||
|
delete t.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Router::start() {
|
int Router::start() {
|
||||||
m_running = true;
|
m_running = true;
|
||||||
int err = bind(m_socket, (struct sockaddr *)&m_address, sizeof(m_address));
|
int err = bind(m_socket, (struct sockaddr *)&m_address, sizeof(m_address));
|
||||||
@@ -105,7 +110,7 @@ void Router::handle(std::string pathPattern,
|
|||||||
// TODO: UNSAFE CHECK BOUNDS
|
// TODO: UNSAFE CHECK BOUNDS
|
||||||
auto tree = m_routes[route[0]];
|
auto tree = m_routes[route[0]];
|
||||||
if (!tree) {
|
if (!tree) {
|
||||||
tree = std::make_shared<Tree>(Tree(route[0]));
|
tree = new Tree(route[0]);
|
||||||
m_routes.insert_or_assign(route[0], tree);
|
m_routes.insert_or_assign(route[0], tree);
|
||||||
}
|
}
|
||||||
tree->add_path(route[1], func);
|
tree->add_path(route[1], func);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "tree.hpp"
|
#include "tree.hpp"
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
namespace http {
|
namespace http {
|
||||||
class Router {
|
class Router {
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::shared_ptr<Tree>> m_routes;
|
std::map<std::string, Tree *> m_routes;
|
||||||
int m_socket;
|
int m_socket;
|
||||||
sockaddr_in m_address;
|
sockaddr_in m_address;
|
||||||
Response Route(Request req);
|
Response Route(Request req);
|
||||||
@@ -34,6 +33,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Router(int port);
|
Router(int port);
|
||||||
|
~Router();
|
||||||
void handle(std::string path_pattern,
|
void handle(std::string path_pattern,
|
||||||
std::function<void(Request, Response *)> func);
|
std::function<void(Request, Response *)> func);
|
||||||
int start();
|
int start();
|
||||||
|
|||||||
42
tree.cpp
42
tree.cpp
@@ -3,7 +3,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
using namespace http;
|
using namespace http;
|
||||||
@@ -23,19 +22,23 @@ Node::Node(std::string sub, bool isValue,
|
|||||||
m_is_dummy = false;
|
m_is_dummy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node::~Node() {
|
||||||
|
for (auto n : m_next) {
|
||||||
|
delete n.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Tree::Tree(std::string method) { m_method = method; }
|
Tree::Tree(std::string method) { m_method = method; }
|
||||||
|
|
||||||
void add_node(std::shared_ptr<Node> const &parent, std::string path,
|
void add_node(Node *parent, std::string path, std::vector<std::string> rest,
|
||||||
std::vector<std::string> rest,
|
std::function<void(Request, Response *)> func) {
|
||||||
std::function<void(Request, Response *)> func) {
|
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_is_dummy = false;
|
curr->m_is_dummy = false;
|
||||||
curr->m_function = func;
|
curr->m_function = func;
|
||||||
} else {
|
} else {
|
||||||
std::shared_ptr<Node> leaf =
|
Node *leaf = new Node{path, false, func};
|
||||||
std::make_shared<Node>(Node{path, false, func});
|
|
||||||
parent->m_next.insert_or_assign(path, leaf);
|
parent->m_next.insert_or_assign(path, leaf);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -49,24 +52,25 @@ void add_node(std::shared_ptr<Node> const &parent, std::string path,
|
|||||||
} else {
|
} else {
|
||||||
auto newPath = rest.front();
|
auto newPath = rest.front();
|
||||||
rest.erase(rest.begin());
|
rest.erase(rest.begin());
|
||||||
std::shared_ptr<Node> leaf = std::make_shared<Node>(Node{path});
|
Node *leaf = new Node{path};
|
||||||
parent->m_next.insert_or_assign(path, leaf);
|
parent->m_next.insert_or_assign(path, leaf);
|
||||||
add_node(leaf, newPath, rest, func);
|
add_node(leaf, newPath, rest, func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tree::add_path(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, "/");
|
||||||
|
|
||||||
if (subPaths.size() == 0 && m_root == nullptr) {
|
if (subPaths.size() == 0 && m_root == nullptr) {
|
||||||
m_root = std::make_shared<Node>(Node{"", false, func});
|
m_root = new Node{"", false, func};
|
||||||
return;
|
return;
|
||||||
} else if (subPaths.size() == 0) {
|
} else if (subPaths.size() == 0) {
|
||||||
|
m_root->m_is_dummy = false;
|
||||||
m_root->m_function = func;
|
m_root->m_function = func;
|
||||||
return;
|
return;
|
||||||
} else if (m_root == nullptr) {
|
} else if (m_root == nullptr) {
|
||||||
m_root = std::make_shared<Node>(Node{""});
|
m_root = new Node{""};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newPath = subPaths.front();
|
auto newPath = subPaths.front();
|
||||||
@@ -74,7 +78,9 @@ void Tree::add_path(std::string path,
|
|||||||
add_node(m_root, newPath, subPaths, func);
|
add_node(m_root, newPath, subPaths, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_node(std::shared_ptr<Node> node, size_t depth, size_t max_depth) {
|
Tree::~Tree() { delete m_root; };
|
||||||
|
|
||||||
|
void print_node(Node *node, size_t depth, size_t max_depth) {
|
||||||
if (depth >= max_depth) {
|
if (depth >= max_depth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -86,11 +92,11 @@ void print_node(std::shared_ptr<Node> node, size_t depth, size_t max_depth) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::function<void(Request, Response *)>>
|
auto traverse(Node *const &parent, std::string path,
|
||||||
traverse(std::shared_ptr<Node> const &parent, std::string path,
|
std::vector<std::string> rest)
|
||||||
std::vector<std::string> rest) {
|
-> std::optional<std::function<void(Request, Response *)>> {
|
||||||
|
|
||||||
std::shared_ptr<Node> curr = parent->m_next[path];
|
Node *curr = parent->m_next[path];
|
||||||
if (rest.size() == 0) {
|
if (rest.size() == 0) {
|
||||||
if (curr != nullptr && !curr->m_is_dummy)
|
if (curr != nullptr && !curr->m_is_dummy)
|
||||||
return curr->m_function;
|
return curr->m_function;
|
||||||
@@ -112,9 +118,9 @@ 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_is_dummy)
|
if (!m_root->m_is_dummy) {
|
||||||
return m_root->m_function;
|
return m_root->m_function;
|
||||||
else
|
} else
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
tree.hpp
7
tree.hpp
@@ -5,7 +5,6 @@
|
|||||||
#include "response.hpp"
|
#include "response.hpp"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
@@ -14,23 +13,25 @@ public:
|
|||||||
bool m_is_value;
|
bool m_is_value;
|
||||||
bool m_is_dummy;
|
bool m_is_dummy;
|
||||||
std::string m_sub_path;
|
std::string m_sub_path;
|
||||||
std::map<std::string, std::shared_ptr<Node>> m_next;
|
std::map<std::string, Node *> m_next;
|
||||||
std::function<void(Request, Response *)> m_function;
|
std::function<void(Request, Response *)> m_function;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node(std::string subPath, bool isValue,
|
Node(std::string subPath, bool isValue,
|
||||||
std::function<void(Request, Response *)>);
|
std::function<void(Request, Response *)>);
|
||||||
Node(std::string subPath);
|
Node(std::string subPath);
|
||||||
|
~Node();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tree {
|
class Tree {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Node> m_root;
|
Node *m_root;
|
||||||
std::string m_method;
|
std::string m_method;
|
||||||
size_t m_depth;
|
size_t m_depth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tree(std::string method);
|
Tree(std::string method);
|
||||||
|
~Tree();
|
||||||
void add_path(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 debug_Print();
|
void debug_Print();
|
||||||
|
|||||||
Reference in New Issue
Block a user