diff --git a/.gitmodules b/.gitmodules index fb47a81..6730611 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/zippuccino"] path = lib/zippuccino url = git@github.com:coding-cpp/zippuccino.git +[submodule "lib/mochios"] + path = lib/mochios + url = git@github.com:coding-cpp/mochios diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b1206c..1fcb8cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,8 @@ target_include_directories(server $ $ $ - $ + $ $ + $ + $ ) diff --git a/assets/github/build.png b/assets/github/build.png index 3f5c48a..075f818 100644 Binary files a/assets/github/build.png and b/assets/github/build.png differ diff --git a/assets/github/start.png b/assets/github/start.png index 97c3531..ee835de 100644 Binary files a/assets/github/start.png and b/assets/github/start.png differ diff --git a/example/main.cpp b/example/main.cpp index 12780c0..7b94e01 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -57,6 +57,13 @@ void about(Request &req, Response &res) { response["submodules"][4]["location"] = "lib/zippuccino"; response["submodules"][4]["name"] = "Zippuccino"; + json::object mochios; + mochios["repository"] = "https://github.com/coding-cpp/mochios"; + mochios["work"] = "HTTP request library for C++"; + mochios["location"] = "lib/mochios"; + mochios["name"] = "Mochios"; + response["submodules"].push_back(mochios); + res.status(STATUS_CODE::OK).json(response).end(); return; } diff --git a/include/expresso/core/router.h b/include/expresso/core/router.h index 04c6459..12e8371 100644 --- a/include/expresso/core/router.h +++ b/include/expresso/core/router.h @@ -37,8 +37,8 @@ class Router { expresso::messages::Response &response); std::map & - fetchMapFromMethod(expresso::enums::method method); - void addRoute(expresso::enums::method method, std::string path, + fetchMapFromMethod(mochios::enums::method method); + void addRoute(mochios::enums::method method, std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)); diff --git a/include/expresso/enums/method.h b/include/expresso/enums/method.h deleted file mode 100644 index e736e46..0000000 --- a/include/expresso/enums/method.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace expresso { - -namespace enums { - -enum class method { GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD }; - -extern const std::set methods; - -} // namespace enums - -} // namespace expresso - -bool operator==(const expresso::enums::method &m, const std::string &str); -bool operator!=(const expresso::enums::method &m, const std::string &str); - -std::ostream &operator<<(std::ostream &os, const expresso::enums::method &m); - -std::string operator+(const expresso::enums::method &m, const std::string &str); -std::string operator+(const std::string &str, const expresso::enums::method &m); diff --git a/include/expresso/messages/cookie.h b/include/expresso/messages/cookie.h index 4cc8a83..5eb69d6 100644 --- a/include/expresso/messages/cookie.h +++ b/include/expresso/messages/cookie.h @@ -1,31 +1,16 @@ #pragma once -#include - -#include +#include namespace expresso { namespace messages { -class Cookie { +class Cookie : public mochios::messages::Cookie { public: - bool secure; - bool httpOnly; - bool partitioned; - - std::string name; - std::string value; - std::string domain; - std::string path; - std::string expires; - std::string maxAge; - std::string sameSite; - Cookie(); + Cookie(const std::string &data); ~Cookie(); - - std::string serialize(); }; } // namespace messages diff --git a/include/expresso/messages/request.h b/include/expresso/messages/request.h index 99e67e9..211c619 100644 --- a/include/expresso/messages/request.h +++ b/include/expresso/messages/request.h @@ -1,15 +1,17 @@ #pragma once +#include + #include namespace expresso { namespace messages { -class Request { +class Request : public mochios::messages::Request { private: public: - Request(); + Request(const std::string &path); ~Request(); bool xhr; @@ -17,23 +19,16 @@ class Request { std::string host; std::string hostname; - expresso::enums::method method; - std::string path; std::string httpVersion; // tempPath used internally for referencing. DO NOT USE IT! Use `path` // instead. std::string tempPath; - - json::object body; - std::vector cookies; - std::map headers; - std::map params; - std::map queries; + std::vector cookies; expresso::messages::Response *res; - void print(); + void print() override; }; } // namespace messages diff --git a/include/expresso/messages/response.h b/include/expresso/messages/response.h index e5d4798..d307712 100644 --- a/include/expresso/messages/response.h +++ b/include/expresso/messages/response.h @@ -7,9 +7,10 @@ #include #include #include +#include +#include #include -#include #include #include @@ -17,16 +18,14 @@ namespace expresso { namespace messages { -class Response { +class Response : public mochios::messages::Response { private: bool hasEnded; int socket; - expresso::enums::STATUS_CODE statusCode; std::string message; std::vector cookies; - std::map headers; void sendToClient(); void sendHeaders(); @@ -51,7 +50,7 @@ class Response { void sendInvalidRange(); void end(); - void print(); + void print() override; }; } // namespace messages diff --git a/include/expresso/middleware/cors.h b/include/expresso/middleware/cors.h index b058bf9..2c700cd 100644 --- a/include/expresso/middleware/cors.h +++ b/include/expresso/middleware/cors.h @@ -15,7 +15,7 @@ class Cors : public Middleware { std::set origins; std::set headers; - std::set methods; + std::set methods; public: Cors(); @@ -23,7 +23,7 @@ class Cors : public Middleware { void allowOrigin(std::string origin); void allowMethod(std::string method); - void allowMethod(expresso::enums::method method); + void allowMethod(mochios::enums::method method); void allowHeader(std::string header); void allowCredentials(bool credentials); diff --git a/lib/mochios b/lib/mochios new file mode 160000 index 0000000..4fa51ea --- /dev/null +++ b/lib/mochios @@ -0,0 +1 @@ +Subproject commit 4fa51eab6a98d54ce0cc6006bb0030e89e66387c diff --git a/src/core/router.cpp b/src/core/router.cpp index f6192ca..f967a91 100644 --- a/src/core/router.cpp +++ b/src/core/router.cpp @@ -25,42 +25,42 @@ expresso::core::Router::~Router() { void expresso::core::Router::get( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::GET, path, handler); + this->addRoute(mochios::enums::method::GET, path, handler); return; } void expresso::core::Router::post( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::POST, path, handler); + this->addRoute(mochios::enums::method::POST, path, handler); return; } void expresso::core::Router::put( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::PUT, path, handler); + this->addRoute(mochios::enums::method::PUT, path, handler); return; } void expresso::core::Router::patch( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::PATCH, path, handler); + this->addRoute(mochios::enums::method::PATCH, path, handler); return; } void expresso::core::Router::del( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::DELETE, path, handler); + this->addRoute(mochios::enums::method::DELETE, path, handler); return; } void expresso::core::Router::options( std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { - this->addRoute(expresso::enums::method::OPTIONS, path, handler); + this->addRoute(mochios::enums::method::OPTIONS, path, handler); return; } @@ -157,20 +157,20 @@ bool expresso::core::Router::handleMiddlewares( std::map & -expresso::core::Router::fetchMapFromMethod(expresso::enums::method method) { +expresso::core::Router::fetchMapFromMethod(mochios::enums::method method) { switch (method) { - case expresso::enums::method::GET: + case mochios::enums::method::GET: return this->getMap; - case expresso::enums::method::POST: + case mochios::enums::method::POST: return this->postMap; - case expresso::enums::method::PUT: + case mochios::enums::method::PUT: return this->putMap; - case expresso::enums::method::PATCH: + case mochios::enums::method::PATCH: return this->patchMap; - case expresso::enums::method::DELETE: + case mochios::enums::method::DELETE: return this->deleteMap; - case expresso::enums::method::OPTIONS: + case mochios::enums::method::OPTIONS: return this->optionsMap; default: logger::error("Invalid method: " + std::to_string(static_cast(method)), @@ -184,7 +184,7 @@ expresso::core::Router::fetchMapFromMethod(expresso::enums::method method) { } void expresso::core::Router::addRoute( - expresso::enums::method method, std::string path, + mochios::enums::method method, std::string path, void (*handler)(expresso::messages::Request &request, expresso::messages::Response &response)) { if (path[0] != '/') { diff --git a/src/core/server.cpp b/src/core/server.cpp index b28a6f0..52db297 100644 --- a/src/core/server.cpp +++ b/src/core/server.cpp @@ -104,7 +104,8 @@ void expresso::core::Server::handleConnection(int clientSocket) { charRequest.resize(totalBytesRead); std::string request(charRequest.data()); - expresso::messages::Response *res = new expresso::messages::Response(clientSocket); + expresso::messages::Response *res = + new expresso::messages::Response(clientSocket); try { expresso::messages::Request req = this->makeRequest(request); @@ -124,7 +125,6 @@ void expresso::core::Server::handleConnection(int clientSocket) { expresso::messages::Request expresso::core::Server::makeRequest(std::string &request) noexcept(false) { - expresso::messages::Request req; std::string line; std::istringstream stream(request); std::getline(stream, line); @@ -132,16 +132,16 @@ expresso::core::Server::makeRequest(std::string &request) noexcept(false) { std::vector parts = brewtils::string::split(line, " "); const std::string method = brewtils::string::upper(parts[0]); std::set::const_iterator methodIter = - expresso::enums::methods.find(method); - if (methodIter == expresso::enums::methods.end()) { + mochios::enums::methods.find(method); + if (methodIter == mochios::enums::methods.end()) { logger::error("Unsupported HTTP method: " + method, "expresso::core::Server::makeRequest(std::string &request) " "noexcept(false)"); } - req.method = static_cast( - std::distance(expresso::enums::methods.begin(), methodIter) - 1); - req.path = parts[1]; + expresso::messages::Request req(parts[1]); + req.method = static_cast( + std::distance(mochios::enums::methods.begin(), methodIter) - 1); req.httpVersion = parts[2]; if (req.httpVersion.substr(0, 5) != "HTTP/") { logger::error("Invalid HTTP version: " + req.httpVersion, @@ -206,8 +206,8 @@ expresso::core::Server::makeRequest(std::string &request) noexcept(false) { req.tempPath = req.tempPath.substr(0, req.tempPath.size() - 1); } - if (req.method == expresso::enums::method::GET || - req.method == expresso::enums::method::HEAD) { + if (req.method == mochios::enums::method::GET || + req.method == mochios::enums::method::HEAD) { return req; } diff --git a/src/enums/method.cpp b/src/enums/method.cpp deleted file mode 100644 index d15e9c7..0000000 --- a/src/enums/method.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include - -const std::set expresso::enums::methods = { - "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"}; - -static const std::unordered_map - methodToString{{expresso::enums::method::GET, "GET"}, - {expresso::enums::method::POST, "POST"}, - {expresso::enums::method::PUT, "PUT"}, - {expresso::enums::method::PATCH, "PATCH"}, - {expresso::enums::method::DELETE, "DELETE"}, - {expresso::enums::method::OPTIONS, "OPTIONS"}, - {expresso::enums::method::HEAD, "HEAD"}}; - -bool operator==(const expresso::enums::method &m, const std::string &str) { - return methodToString.at(m) == str; -} - -bool operator!=(const expresso::enums::method &m, const std::string &str) { - return !(m == str); -} - -std::ostream &operator<<(std::ostream &os, const expresso::enums::method &m) { - os << methodToString.at(m); - return os; -} - -std::string operator+(const expresso::enums::method &m, - const std::string &str) { - return methodToString.at(m) + str; -} - -std::string operator+(const std::string &str, - const expresso::enums::method &m) { - return str + methodToString.at(m); -} diff --git a/src/messages/cookie.cpp b/src/messages/cookie.cpp index 122dcd6..794dfae 100644 --- a/src/messages/cookie.cpp +++ b/src/messages/cookie.cpp @@ -1,40 +1,10 @@ #include -expresso::messages::Cookie::Cookie() - : secure(false), httpOnly(false), partitioned(false), name(""), value(""), - domain(""), path(""), expires(""), maxAge(""), sameSite("") { +expresso::messages::Cookie::Cookie() : mochios::messages::Cookie() { return; } + +expresso::messages::Cookie::Cookie(const std::string &data) + : mochios::messages::Cookie(data) { return; } -expresso::messages::Cookie::~Cookie() { return; } - -std::string expresso::messages::Cookie::serialize() { - std::string cookieString = - this->name + "=" + brewtils::url::encode(this->value); - if (!this->domain.empty()) { - cookieString += "; Domain=" + this->domain; - } - if (!this->path.empty()) { - cookieString += "; Path=" + this->path; - } - if (!this->expires.empty()) { - cookieString += "; Expires=" + this->expires; - } - if (!this->maxAge.empty()) { - cookieString += "; Max-Age=" + this->maxAge; - } - if (!this->sameSite.empty()) { - cookieString += "; SameSite=" + this->sameSite; - } - if (this->secure) { - cookieString += "; Secure"; - } - if (this->httpOnly) { - cookieString += "; HttpOnly"; - } - if (this->partitioned) { - cookieString += "; Partitioned"; - } - - return cookieString; -} \ No newline at end of file +expresso::messages::Cookie::~Cookie() { return; } \ No newline at end of file diff --git a/src/messages/request.cpp b/src/messages/request.cpp index f71da70..e4b9369 100644 --- a/src/messages/request.cpp +++ b/src/messages/request.cpp @@ -1,7 +1,8 @@ #include -expresso::messages::Request::Request() - : xhr(false), res(nullptr), contentLength(0) { +expresso::messages::Request::Request(const std::string &path) + : xhr(false), res(nullptr), contentLength(0), + mochios::messages::Request(path) { return; } diff --git a/src/messages/response.cpp b/src/messages/response.cpp index 6e09845..aed379e 100644 --- a/src/messages/response.cpp +++ b/src/messages/response.cpp @@ -2,9 +2,9 @@ #include expresso::messages::Response::Response(int clientSocket) - : hasEnded(false), socket(clientSocket), - statusCode(expresso::enums::STATUS_CODE::OK), message("") { + : hasEnded(false), socket(clientSocket), message("") { this->set("connection", "close"); + this->statusCode = expresso::enums::STATUS_CODE::OK; return; } diff --git a/src/middleware/cors.cpp b/src/middleware/cors.cpp index 994d22c..e834c7c 100644 --- a/src/middleware/cors.cpp +++ b/src/middleware/cors.cpp @@ -7,9 +7,9 @@ expresso::middleware::Cors::Cors() this->headers.insert(_header); } - this->allowMethod(expresso::enums::method::GET); - this->allowMethod(expresso::enums::method::POST); - this->allowMethod(expresso::enums::method::OPTIONS); + this->allowMethod(mochios::enums::method::GET); + this->allowMethod(mochios::enums::method::POST); + this->allowMethod(mochios::enums::method::OPTIONS); return; } @@ -28,20 +28,20 @@ void expresso::middleware::Cors::allowOrigin(std::string origin) { void expresso::middleware::Cors::allowMethod(std::string method) { std::set::const_iterator methodIter = - expresso::enums::methods.find(method); - if (methodIter == expresso::enums::methods.end()) { + mochios::enums::methods.find(method); + if (methodIter == mochios::enums::methods.end()) { logger::error( "Invalid CORS method: " + method, "void expresso::middleware::Cors::allowMethod(std::string method)"); return; } - this->methods.insert(static_cast( - std::distance(expresso::enums::methods.begin(), methodIter) - 1)); + this->methods.insert(static_cast( + std::distance(mochios::enums::methods.begin(), methodIter) - 1)); return; } -void expresso::middleware::Cors::allowMethod(expresso::enums::method method) { +void expresso::middleware::Cors::allowMethod(mochios::enums::method method) { this->methods.insert(method); return; } diff --git a/src/middleware/static_serve.cpp b/src/middleware/static_serve.cpp index b4c7b31..2c064e8 100644 --- a/src/middleware/static_serve.cpp +++ b/src/middleware/static_serve.cpp @@ -11,7 +11,7 @@ expresso::middleware::StaticServe::~StaticServe() { return; } bool expresso::middleware::StaticServe::use(expresso::messages::Request &req, expresso::messages::Response &res) { - if (req.method != expresso::enums::method::GET) { + if (req.method != mochios::enums::method::GET) { return true; }