diff --git a/include/niven/Cookie.h b/include/niven/Cookie.h index 1b8032e..3d37013 100644 --- a/include/niven/Cookie.h +++ b/include/niven/Cookie.h @@ -25,7 +25,7 @@ namespace niven Cookie(std::string name, std::string value, const DateTime &expires) : name(name), value(value), expires(expires) {} // Build the cookie string. - std::string Build(); + std::string Build() const; // Enable the Secure flag. Cookie &Secure(); diff --git a/include/niven/Dependencies.h b/include/niven/Dependencies.h deleted file mode 100644 index 5384c94..0000000 --- a/include/niven/Dependencies.h +++ /dev/null @@ -1,81 +0,0 @@ -// #pragma once - -// #include -// #include -// #include -// #include - - -// namespace niven -// { -// // A dependency container implementation with basic functionality. -// class Dependencies -// { -// public: - -// // Register a concrete class type with the container. Instances will be created (using the supplied -// // constructor parameters) each time it is resolved. -// template void Register(Parameters... parameters) -// { -// static_assert(std::is_base_of::value, "Concrete class must be derived from Interface type"); - -// this->containers[typeid(Interface).name()].Set([parameters...]() { return new Concrete(parameters...); }); -// } - - -// // Register a singleton with the container. Any registered singleton must be thread safe since -// // it will be accessed from concurrent request handlers. -// template void Register(std::shared_ptr singleton) -// { -// auto copy = new std::shared_ptr(singleton); - -// this->containers[typeid(Interface).name()].Set([=]() { return copy; }, [=]() { delete copy; }); -// } - - -// // Resolve the required type. Use the same function to retrieve singletons -// // and standard instances alike. -// template std::shared_ptr Resolve() -// { -// auto &con = this->containers[typeid(Interface).name()]; - -// if (con.retrieve) -// { -// return con.dispose -// ? *static_cast *>(con.retrieve()) -// : std::shared_ptr((Interface *)con.retrieve()); -// } - -// return nullptr; -// } - - -// private: - -// // Container for a given base type. It simply contains functions -// // for dependency retrieval and cleaning up. -// struct Container -// { -// std::function retrieve = nullptr; -// std::function dispose = nullptr; // Singleton has a dispose - - -// void Set(std::function retrieve, std::function dispose = nullptr) -// { -// if (this->dispose) this->dispose(); - -// this->retrieve = retrieve; -// this->dispose = dispose; -// } - - -// ~Container() -// { -// if (this->dispose) this->dispose(); -// } -// }; - - -// std::map containers; -// }; -// } diff --git a/include/niven/Host.h b/include/niven/Host.h index d8b6acf..6de3e1b 100644 --- a/include/niven/Host.h +++ b/include/niven/Host.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/src/examples/example.cpp b/src/examples/example.cpp index 1bb9616..883ecd8 100644 --- a/src/examples/example.cpp +++ b/src/examples/example.cpp @@ -5,38 +5,39 @@ #include #include +#include -#include "examples/Simple.hpp" -#include "examples/Entities.hpp" -#include "examples/Dependencies.hpp" -#include "examples/Pipeline.hpp" -#include "examples/Cookies.hpp" -#include "examples/Headers.hpp" -#include "examples/Query.hpp" -#include "examples/RouteCaptures.hpp" -#include "examples/Hashing.hpp" -#include "examples/Files.hpp" +// #include "examples/Simple.hpp" +// #include "examples/Entities.hpp" +// #include "examples/Dependencies.hpp" +// #include "examples/Pipeline.hpp" +// #include "examples/Cookies.hpp" +// #include "examples/Headers.hpp" +// #include "examples/Query.hpp" +// #include "examples/RouteCaptures.hpp" +// #include "examples/Hashing.hpp" +// #include "examples/Files.hpp" -using namespace std; -using namespace emg; -using namespace niven; +// using namespace std; +// using namespace emg; +// using namespace niven; bool run = true; -condition_variable condition; +std::condition_variable condition; int main(int argc, char **argv) { // Enable logging to stdout - Log::Initialise({ make_unique() }); - Log::Verbosity("info"); + emg::Log::Initialise({ std::make_unique() }); + emg::Log::Verbosity("info"); // Catch the interrupt/quit signals and handle appropriately signal(SIGINT, [](int) { run = false; condition.notify_one(); }); signal(SIGQUIT, [](int) { run = false; condition.notify_one(); }); - NivenHost host; + niven::NivenHost host; // Configure the host to listen on port 8090 host.Listen(8090); @@ -50,11 +51,11 @@ int main(int argc, char **argv) // Refer to https://github.com/emergent-design/libemergent/ for more // information about the C++ Redis wrappers. This Redis connection is // used in the "include/examples/Dependencies.hpp" example. - host.Register(make_shared()); + host.Register(std::make_shared()); // Resolve the singleton and invoke the Initialise function which will // connect to redis using the default parameters (127.0.0.1:6379). - host.Resolve()->Initialise(); + host.Resolve()->Initialise(); // Start the host running. This function will return true if successfully @@ -62,10 +63,11 @@ int main(int argc, char **argv) // variable to wait for an interrupt or quit signal from the user. if (host.Run()) { - cout << "Listening on port 8090" << endl; + std::cout << "Listening on port 8090\n"; + + std::mutex m; + std::unique_lock lock(m); - mutex m; - unique_lock lock(m); while (run) { condition.wait(lock); @@ -74,7 +76,10 @@ int main(int argc, char **argv) // Tell the host to stop listening. host.Stop(); } - else cout << "Failed to initialise host" << endl; + else + { + std::cout << "Failed to initialise host\n"; + } return 0; } diff --git a/include/examples/Cookies.hpp b/src/examples/modules/Cookies.cpp similarity index 100% rename from include/examples/Cookies.hpp rename to src/examples/modules/Cookies.cpp diff --git a/include/examples/Dependencies.hpp b/src/examples/modules/Dependencies.cpp similarity index 100% rename from include/examples/Dependencies.hpp rename to src/examples/modules/Dependencies.cpp diff --git a/include/examples/Entities.hpp b/src/examples/modules/Entities.cpp similarity index 100% rename from include/examples/Entities.hpp rename to src/examples/modules/Entities.cpp diff --git a/include/examples/Files.hpp b/src/examples/modules/Files.cpp similarity index 100% rename from include/examples/Files.hpp rename to src/examples/modules/Files.cpp diff --git a/include/examples/Hashing.hpp b/src/examples/modules/Hashing.cpp similarity index 100% rename from include/examples/Hashing.hpp rename to src/examples/modules/Hashing.cpp diff --git a/include/examples/Headers.hpp b/src/examples/modules/Headers.cpp similarity index 100% rename from include/examples/Headers.hpp rename to src/examples/modules/Headers.cpp diff --git a/include/examples/Pipeline.hpp b/src/examples/modules/Pipeline.cpp similarity index 100% rename from include/examples/Pipeline.hpp rename to src/examples/modules/Pipeline.cpp diff --git a/include/examples/Query.hpp b/src/examples/modules/Query.cpp similarity index 100% rename from include/examples/Query.hpp rename to src/examples/modules/Query.cpp diff --git a/include/examples/RouteCaptures.hpp b/src/examples/modules/RouteCaptures.cpp similarity index 100% rename from include/examples/RouteCaptures.hpp rename to src/examples/modules/RouteCaptures.cpp diff --git a/include/examples/Simple.hpp b/src/examples/modules/Simple.cpp similarity index 100% rename from include/examples/Simple.hpp rename to src/examples/modules/Simple.cpp diff --git a/src/examples/premake5.lua b/src/examples/premake5.lua index 9b8cc52..6bff057 100644 --- a/src/examples/premake5.lua +++ b/src/examples/premake5.lua @@ -17,10 +17,10 @@ solution "examples" kind "ConsoleApp" targetdir "bin" links { "niven", "hiredis", "pthread", "stdc++fs" } - files { "example.cpp" } + files { "example.cpp", "modules/**.cpp" } project "ssl" kind "ConsoleApp" targetdir "bin" links { "niven", "pthread" } - files { "ssl.cpp" } + files { "ssl.cpp", "modules/Simple.cpp" } diff --git a/src/examples/ssl.cpp b/src/examples/ssl.cpp index 3feab29..9bf9be1 100644 --- a/src/examples/ssl.cpp +++ b/src/examples/ssl.cpp @@ -6,12 +6,7 @@ // #include #include -#include "examples/Simple.hpp" - - -using namespace std; -using namespace emg; -using namespace niven; +// #include "examples/Simple.hpp" auto KEY = R"ssl( @@ -55,20 +50,20 @@ auto CERTIFICATE = R"ssl( bool run = true; -condition_variable condition; +std::condition_variable condition; int main(int argc, char **argv) { // Enable logging to stdout - Log::Initialise({ make_unique() }); - Log::Verbosity("info"); + emg::Log::Initialise({ std::make_unique() }); + emg::Log::Verbosity("info"); // Catch the interrupt/quit signals and handle appropriately signal(SIGINT, [](int) { run = false; condition.notify_one(); }); signal(SIGQUIT, [](int) { run = false; condition.notify_one(); }); - NivenHost host; + niven::NivenHost host; // Listen on port 8090 and enable SSL using an embedded key and certificate. host.Listen(8090).EnableSSL(KEY, CERTIFICATE); @@ -82,15 +77,22 @@ int main(int argc, char **argv) // variable to wait for an interrupt or quit signal from the user. if (host.Run()) { - cout << "Listening on port 8090" << endl; + std::cout << "Listening on port 8090\n"; + + std::mutex m; + std::unique_lock lock(m); - mutex m; - unique_lock lock(m); - while (run) condition.wait(lock); + while (run) + { + condition.wait(lock); + } host.Stop(); } - else cout << "Failed to initialise host" << endl; + else + { + std::cout << "Failed to initialise host\n"; + } return 0; } diff --git a/src/niven/Cookie.cpp b/src/niven/Cookie.cpp index 841d6a0..a5437c1 100644 --- a/src/niven/Cookie.cpp +++ b/src/niven/Cookie.cpp @@ -9,7 +9,7 @@ using namespace emergent; namespace niven { // Build the cookie string. - string Cookie::Build() + string Cookie::Build() const { auto result = String::format("%s=%s; Path=%s", this->name, this->value, this->path); diff --git a/src/niven/Response.cpp b/src/niven/Response.cpp index abc9b54..e1b2793 100644 --- a/src/niven/Response.cpp +++ b/src/niven/Response.cpp @@ -63,39 +63,40 @@ namespace niven int Response::Send(MHD_Connection *connection) { - if (!this->path.empty()) + MHD_Response *response = nullptr; + + if (this->path.empty()) { - if (auto file = fopen(this->path.c_str(), "rb")) - { - auto response = MHD_create_response_from_callback( - fs::file_size(this->path), - 32 * 1024, - [](void *file, uint64_t pos, char *buffer, size_t max) { - fseek((FILE *)file, pos, SEEK_SET); - return (ssize_t)fread(buffer, 1, max, (FILE *)file); - }, - file, - [](void *file) { fclose((FILE *)file); } - ); - - MHD_add_response_header(response, "Server", "niven/0.1"); - MHD_add_response_header(response, "Keep-Alive", "timeout=60"); - - int result = MHD_queue_response(connection, (int)this->status, response); - - MHD_destroy_response(response); - - return result; - } - - this->status = Http::NotFound; + // auto response = MHD_create_response_from_buffer(this->data.size(), (void *)this->data.data(), MHD_RESPMEM_PERSISTENT); + response = MHD_create_response_from_buffer(this->data.size(), (void *)this->data.data(), MHD_RESPMEM_MUST_COPY); + } + else if (auto file = fopen(this->path.c_str(), "rb")) + { + response = MHD_create_response_from_callback( + fs::file_size(this->path), + 32 * 1024, + [](void *file, uint64_t pos, char *buffer, size_t max) { + fseek((FILE *)file, pos, SEEK_SET); + return (ssize_t)fread(buffer, 1, max, (FILE *)file); + }, + file, + [](void *file) { fclose((FILE *)file); } + ); + } + else + { + response = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_MUST_COPY); + this->status = Http::NotFound; } - // auto response = MHD_create_response_from_buffer(this->data.size(), (void *)this->data.data(), MHD_RESPMEM_PERSISTENT); - auto response = MHD_create_response_from_buffer(this->data.size(), (void *)this->data.data(), MHD_RESPMEM_MUST_COPY); - - for (auto &h : this->headers) MHD_add_response_header(response, h.first.c_str(), h.second.c_str()); - for (auto &c : this->cookies) MHD_add_response_header(response, "Set-Cookie", c.Build().c_str()); + for (const auto &[name, value] : this->headers) + { + MHD_add_response_header(response, name.c_str(), value.c_str()); + } + for (const auto &c : this->cookies) + { + MHD_add_response_header(response, "Set-Cookie", c.Build().c_str()); + } MHD_add_response_header(response, "Server", "niven/0.1"); MHD_add_response_header(response, "Keep-Alive", "timeout=60");