From cd1be59cfaedd536b86aa7b58654eb5b4e2ef76c Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 6 May 2017 19:48:44 +0100 Subject: [PATCH] Pass the output stream and cgi_env to Response. Mask the fact that they are globals, because I need to be able to pass different classes in order to be able to write unit tests for response classes. --- src/tawashi/main.cpp | 11 +++++---- src/tawashi_implem/cgi_env.hpp | 3 ++- src/tawashi_implem/index_response.cpp | 8 +++++-- src/tawashi_implem/index_response.hpp | 6 ++++- src/tawashi_implem/pastie_response.cpp | 9 +++++-- src/tawashi_implem/pastie_response.hpp | 6 ++++- src/tawashi_implem/response.cpp | 25 +++++++++++++++----- src/tawashi_implem/response.hpp | 10 ++++++-- src/tawashi_implem/response_factory.cpp | 9 ++++--- src/tawashi_implem/response_factory.hpp | 8 +++++-- src/tawashi_implem/submit_paste_response.cpp | 8 +++++-- src/tawashi_implem/submit_paste_response.hpp | 6 ++++- 12 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/tawashi/main.cpp b/src/tawashi/main.cpp index e062613..4a3f31d 100644 --- a/src/tawashi/main.cpp +++ b/src/tawashi/main.cpp @@ -32,6 +32,7 @@ #include #include #include +#include //www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4150.pdf @@ -53,8 +54,8 @@ namespace { } template - std::unique_ptr make_response (const Kakoune::SafePtr& parSettings) { - return static_cast>(std::make_unique(parSettings)); + std::unique_ptr make_response (const Kakoune::SafePtr& parSettings, const Kakoune::SafePtr& parCgiEnv) { + return static_cast>(std::make_unique(parSettings, &std::cout, parCgiEnv)); } void fill_defaults (tawashi::SettingsBag& parSettings) { @@ -100,15 +101,15 @@ int main() { spdlog::set_level(static_cast(logging_level._to_integral())); } - tawashi::cgi::Env cgi_env; - tawashi::ResponseFactory resp_factory(settings); + auto cgi_env = SafeStackObject(); + tawashi::ResponseFactory resp_factory(settings, cgi_env); SPDLOG_TRACE(statuslog, "Registering makers in the response factory"); resp_factory.register_maker("index.cgi", &make_response); resp_factory.register_maker("", &make_response); resp_factory.register_maker("paste.cgi", &make_response); resp_factory.register_jolly_maker(&make_response); - std::unique_ptr response = resp_factory.make_response(cgi_env.path_info().substr(1)); + std::unique_ptr response = resp_factory.make_response(cgi_env->path_info().substr(1)); response->send(); return 0; diff --git a/src/tawashi_implem/cgi_env.hpp b/src/tawashi_implem/cgi_env.hpp index 9ed7bf1..10f441d 100644 --- a/src/tawashi_implem/cgi_env.hpp +++ b/src/tawashi_implem/cgi_env.hpp @@ -20,6 +20,7 @@ #include "split_get_vars.hpp" #include "duckhandy/compatibility.h" #include "escapist.hpp" +#include "kakoune/safe_ptr.hh" #include #include #include @@ -30,7 +31,7 @@ namespace tawashi { namespace cgi { - class Env { + class Env : public Kakoune::SafeCountable { public: struct VersionInfo { boost::string_ref name; diff --git a/src/tawashi_implem/index_response.cpp b/src/tawashi_implem/index_response.cpp index f9d2a9e..e64b356 100644 --- a/src/tawashi_implem/index_response.cpp +++ b/src/tawashi_implem/index_response.cpp @@ -19,8 +19,12 @@ #include namespace tawashi { - IndexResponse::IndexResponse (const Kakoune::SafePtr& parSettings) : - Response(Response::ContentType, "text/html", parSettings, false) + IndexResponse::IndexResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ) : + Response(Response::ContentType, "text/html", parSettings, parStreamOut, parCgiEnv, false) { } } //namespace tawashi diff --git a/src/tawashi_implem/index_response.hpp b/src/tawashi_implem/index_response.hpp index 7a0fe9f..66963ae 100644 --- a/src/tawashi_implem/index_response.hpp +++ b/src/tawashi_implem/index_response.hpp @@ -23,7 +23,11 @@ namespace tawashi { class IndexResponse : public Response { public: - explicit IndexResponse (const Kakoune::SafePtr& parSettings); + IndexResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ); protected: virtual boost::string_ref page_basename() const override { return boost::string_ref("index"); } diff --git a/src/tawashi_implem/pastie_response.cpp b/src/tawashi_implem/pastie_response.cpp index 2637352..ac556a7 100644 --- a/src/tawashi_implem/pastie_response.cpp +++ b/src/tawashi_implem/pastie_response.cpp @@ -19,6 +19,7 @@ #include "incredis/incredis.hpp" #include "settings_bag.hpp" #include "escapist.hpp" +#include "cgi_env.hpp" #include #include #include @@ -29,8 +30,12 @@ namespace tawashi { const char g_nolang_token[] = "plaintext"; } //unnamed namespace - PastieResponse::PastieResponse (const Kakoune::SafePtr& parSettings) : - Response(Response::ContentType, "text/html", parSettings, true), + PastieResponse::PastieResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ) : + Response(Response::ContentType, "text/html", parSettings, parStreamOut, parCgiEnv, true), m_langmap_dir(parSettings->as("langmap_dir")), m_plain_text(false), m_syntax_highlight(true) diff --git a/src/tawashi_implem/pastie_response.hpp b/src/tawashi_implem/pastie_response.hpp index 72f59ee..8301f99 100644 --- a/src/tawashi_implem/pastie_response.hpp +++ b/src/tawashi_implem/pastie_response.hpp @@ -24,7 +24,11 @@ namespace tawashi { class PastieResponse : public Response { public: - explicit PastieResponse (const Kakoune::SafePtr& parSettings); + PastieResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ); protected: virtual boost::string_ref page_basename() const override { return boost::string_ref("text"); } diff --git a/src/tawashi_implem/response.cpp b/src/tawashi_implem/response.cpp index 79e0bff..a92a5e0 100644 --- a/src/tawashi_implem/response.cpp +++ b/src/tawashi_implem/response.cpp @@ -22,6 +22,7 @@ #include "duckhandy/stringize.h" #include "pathname/pathname.hpp" #include "list_highlight_langs.hpp" +#include "cgi_env.hpp" #include #include #include @@ -104,14 +105,26 @@ namespace tawashi { }; } //unnamed namespace - Response::Response (Types parRespType, std::string&& parValue, const Kakoune::SafePtr& parSettings, bool parWantRedis) : + Response::Response ( + Types parRespType, + std::string&& parValue, + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv, + bool parWantRedis + ) : m_resp_value(std::move(parValue)), //m_page_basename(fetch_page_basename(m_cgi_env)), + m_cgi_env(parCgiEnv), m_settings(parSettings), m_website_root(make_root_path(*parSettings)), m_resp_type(parRespType), + m_stream_out(parStreamOut), m_header_sent(false) { + assert(m_cgi_env); + assert(m_stream_out); + if (parWantRedis) { m_redis = std::make_unique(make_incredis(*parSettings)); m_redis->connect(); @@ -166,16 +179,16 @@ namespace tawashi { switch (m_resp_type) { case ContentType: SPDLOG_TRACE(statuslog, "Response is a Content-type (data)"); - std::cout << "Content-type: " << m_resp_value << "\n\n"; + *m_stream_out << "Content-type: " << m_resp_value << "\n\n"; break; case Location: SPDLOG_TRACE(statuslog, "Response is a Location (redirect)"); - std::cout << "Location: " << m_resp_value << "\n\n"; + *m_stream_out << "Location: " << m_resp_value << "\n\n"; break; } SPDLOG_TRACE(statuslog, "Rendering in mustache"); - std::cout << mstch::render( + *m_stream_out << mstch::render( on_mustache_retrieve(), mustache_context, std::bind( @@ -187,7 +200,7 @@ namespace tawashi { ) ); SPDLOG_TRACE(statuslog, "Flushing output"); - std::cout.flush(); + m_stream_out->flush(); } std::string Response::on_mustache_retrieve() { @@ -195,7 +208,7 @@ namespace tawashi { } const cgi::Env& Response::cgi_env() const { - return m_cgi_env; + return *m_cgi_env; } void Response::change_type (Types parRespType, std::string&& parValue) { diff --git a/src/tawashi_implem/response.hpp b/src/tawashi_implem/response.hpp index e111b2b..da524b3 100644 --- a/src/tawashi_implem/response.hpp +++ b/src/tawashi_implem/response.hpp @@ -17,7 +17,6 @@ #pragma once -#include "cgi_env.hpp" #include "mstch/mstch.hpp" #include "kakoune/safe_ptr.hh" #include @@ -32,6 +31,10 @@ namespace redis { namespace tawashi { class SettingsBag; + namespace cgi { + class Env; + } //namespace cgi + class Response { public: virtual ~Response() noexcept; @@ -48,6 +51,8 @@ namespace tawashi { Types parRespType, std::string&& parValue, const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv, bool parWantRedis ); const cgi::Env& cgi_env() const; @@ -63,12 +68,13 @@ namespace tawashi { virtual void on_mustache_prepare (mstch::map& parContext); virtual std::string on_mustache_retrieve(); - cgi::Env m_cgi_env; std::string m_resp_value; + Kakoune::SafePtr m_cgi_env; Kakoune::SafePtr m_settings; std::string m_website_root; Types m_resp_type; std::unique_ptr m_redis; + std::ostream* m_stream_out; bool m_header_sent; }; } //namespace tawashi diff --git a/src/tawashi_implem/response_factory.cpp b/src/tawashi_implem/response_factory.cpp index f1bd7b7..208e2cd 100644 --- a/src/tawashi_implem/response_factory.cpp +++ b/src/tawashi_implem/response_factory.cpp @@ -17,6 +17,7 @@ #include "response_factory.hpp" #include "settings_bag.hpp" +#include "cgi_env.hpp" #include #include @@ -28,12 +29,14 @@ namespace tawashi { Kakoune::SafePtr settings; boost::container::flat_map makers; ResponseMakerFunc jolly_maker; + Kakoune::SafePtr cgi_env; }; - ResponseFactory::ResponseFactory (const Kakoune::SafePtr& parSettings) : + ResponseFactory::ResponseFactory (const Kakoune::SafePtr& parSettings, const Kakoune::SafePtr& parCgiEnv) : m_local_data(std::make_unique()) { m_local_data->settings = parSettings; + m_local_data->cgi_env = parCgiEnv; } ResponseFactory::~ResponseFactory() noexcept = default; @@ -43,10 +46,10 @@ namespace tawashi { auto maker_it = m_local_data->makers.find(std::string(parName.data(), parName.size())); if (m_local_data->makers.end() != maker_it) { - return maker_it->second(m_local_data->settings); + return maker_it->second(m_local_data->settings, m_local_data->cgi_env); } else if (m_local_data->jolly_maker) { - return m_local_data->jolly_maker(m_local_data->settings); + return m_local_data->jolly_maker(m_local_data->settings, m_local_data->cgi_env); } else { assert(false); diff --git a/src/tawashi_implem/response_factory.hpp b/src/tawashi_implem/response_factory.hpp index 8b49e72..bc42e92 100644 --- a/src/tawashi_implem/response_factory.hpp +++ b/src/tawashi_implem/response_factory.hpp @@ -24,11 +24,15 @@ namespace tawashi { class SettingsBag; + namespace cgi { + class Env; + } //namespace cgi + class ResponseFactory { public: - typedef std::function(const Kakoune::SafePtr&)> ResponseMakerFunc; + typedef std::function(const Kakoune::SafePtr&, const Kakoune::SafePtr& parCgiEnv)> ResponseMakerFunc; - explicit ResponseFactory (const Kakoune::SafePtr& parSettings); + explicit ResponseFactory (const Kakoune::SafePtr& parSettings, const Kakoune::SafePtr& parCgiEnv); ~ResponseFactory() noexcept; std::unique_ptr make_response(const boost::string_ref& parName); diff --git a/src/tawashi_implem/submit_paste_response.cpp b/src/tawashi_implem/submit_paste_response.cpp index 252b867..428f334 100644 --- a/src/tawashi_implem/submit_paste_response.cpp +++ b/src/tawashi_implem/submit_paste_response.cpp @@ -60,8 +60,12 @@ namespace tawashi { } } //unnamed namespace - SubmitPasteResponse::SubmitPasteResponse (const Kakoune::SafePtr& parSettings) : - Response(Response::ContentType, "text/plain", parSettings, true) + SubmitPasteResponse::SubmitPasteResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ) : + Response(Response::ContentType, "text/plain", parSettings, parStreamOut, parCgiEnv, true) { } diff --git a/src/tawashi_implem/submit_paste_response.hpp b/src/tawashi_implem/submit_paste_response.hpp index 6bc4482..55ad0f5 100644 --- a/src/tawashi_implem/submit_paste_response.hpp +++ b/src/tawashi_implem/submit_paste_response.hpp @@ -25,7 +25,11 @@ namespace tawashi { class SubmitPasteResponse : public Response { public: - explicit SubmitPasteResponse (const Kakoune::SafePtr& parSettings); + SubmitPasteResponse ( + const Kakoune::SafePtr& parSettings, + std::ostream* parStreamOut, + const Kakoune::SafePtr& parCgiEnv + ); protected: virtual boost::string_ref page_basename() const override { return boost::string_ref("paste"); }