mirror of
https://github.com/KingDuckZ/kamokan.git
synced 2025-07-02 14:04:16 +00:00
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.
This commit is contained in:
parent
8980a1d1ff
commit
cd1be59cfa
12 changed files with 81 additions and 28 deletions
|
@ -32,6 +32,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
//www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4150.pdf
|
//www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4150.pdf
|
||||||
|
|
||||||
|
@ -53,8 +54,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unique_ptr<tawashi::Response> make_response (const Kakoune::SafePtr<tawashi::SettingsBag>& parSettings) {
|
std::unique_ptr<tawashi::Response> make_response (const Kakoune::SafePtr<tawashi::SettingsBag>& parSettings, const Kakoune::SafePtr<tawashi::cgi::Env>& parCgiEnv) {
|
||||||
return static_cast<std::unique_ptr<tawashi::Response>>(std::make_unique<T>(parSettings));
|
return static_cast<std::unique_ptr<tawashi::Response>>(std::make_unique<T>(parSettings, &std::cout, parCgiEnv));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_defaults (tawashi::SettingsBag& parSettings) {
|
void fill_defaults (tawashi::SettingsBag& parSettings) {
|
||||||
|
@ -100,15 +101,15 @@ int main() {
|
||||||
spdlog::set_level(static_cast<decltype(spdlog::level::trace)>(logging_level._to_integral()));
|
spdlog::set_level(static_cast<decltype(spdlog::level::trace)>(logging_level._to_integral()));
|
||||||
}
|
}
|
||||||
|
|
||||||
tawashi::cgi::Env cgi_env;
|
auto cgi_env = SafeStackObject<tawashi::cgi::Env>();
|
||||||
tawashi::ResponseFactory resp_factory(settings);
|
tawashi::ResponseFactory resp_factory(settings, cgi_env);
|
||||||
SPDLOG_TRACE(statuslog, "Registering makers in the response factory");
|
SPDLOG_TRACE(statuslog, "Registering makers in the response factory");
|
||||||
resp_factory.register_maker("index.cgi", &make_response<IndexResponse>);
|
resp_factory.register_maker("index.cgi", &make_response<IndexResponse>);
|
||||||
resp_factory.register_maker("", &make_response<IndexResponse>);
|
resp_factory.register_maker("", &make_response<IndexResponse>);
|
||||||
resp_factory.register_maker("paste.cgi", &make_response<SubmitPasteResponse>);
|
resp_factory.register_maker("paste.cgi", &make_response<SubmitPasteResponse>);
|
||||||
resp_factory.register_jolly_maker(&make_response<PastieResponse>);
|
resp_factory.register_jolly_maker(&make_response<PastieResponse>);
|
||||||
|
|
||||||
std::unique_ptr<Response> response = resp_factory.make_response(cgi_env.path_info().substr(1));
|
std::unique_ptr<Response> response = resp_factory.make_response(cgi_env->path_info().substr(1));
|
||||||
response->send();
|
response->send();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "split_get_vars.hpp"
|
#include "split_get_vars.hpp"
|
||||||
#include "duckhandy/compatibility.h"
|
#include "duckhandy/compatibility.h"
|
||||||
#include "escapist.hpp"
|
#include "escapist.hpp"
|
||||||
|
#include "kakoune/safe_ptr.hh"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
|
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
namespace cgi {
|
namespace cgi {
|
||||||
class Env {
|
class Env : public Kakoune::SafeCountable {
|
||||||
public:
|
public:
|
||||||
struct VersionInfo {
|
struct VersionInfo {
|
||||||
boost::string_ref name;
|
boost::string_ref name;
|
||||||
|
|
|
@ -19,8 +19,12 @@
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
IndexResponse::IndexResponse (const Kakoune::SafePtr<SettingsBag>& parSettings) :
|
IndexResponse::IndexResponse (
|
||||||
Response(Response::ContentType, "text/html", parSettings, false)
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
) :
|
||||||
|
Response(Response::ContentType, "text/html", parSettings, parStreamOut, parCgiEnv, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
} //namespace tawashi
|
} //namespace tawashi
|
||||||
|
|
|
@ -23,7 +23,11 @@
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class IndexResponse : public Response {
|
class IndexResponse : public Response {
|
||||||
public:
|
public:
|
||||||
explicit IndexResponse (const Kakoune::SafePtr<SettingsBag>& parSettings);
|
IndexResponse (
|
||||||
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual boost::string_ref page_basename() const override { return boost::string_ref("index"); }
|
virtual boost::string_ref page_basename() const override { return boost::string_ref("index"); }
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "incredis/incredis.hpp"
|
#include "incredis/incredis.hpp"
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
#include "escapist.hpp"
|
#include "escapist.hpp"
|
||||||
|
#include "cgi_env.hpp"
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <srchilite/sourcehighlight.h>
|
#include <srchilite/sourcehighlight.h>
|
||||||
#include <srchilite/langmap.h>
|
#include <srchilite/langmap.h>
|
||||||
|
@ -29,8 +30,12 @@ namespace tawashi {
|
||||||
const char g_nolang_token[] = "plaintext";
|
const char g_nolang_token[] = "plaintext";
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
PastieResponse::PastieResponse (const Kakoune::SafePtr<SettingsBag>& parSettings) :
|
PastieResponse::PastieResponse (
|
||||||
Response(Response::ContentType, "text/html", parSettings, true),
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
) :
|
||||||
|
Response(Response::ContentType, "text/html", parSettings, parStreamOut, parCgiEnv, true),
|
||||||
m_langmap_dir(parSettings->as<std::string>("langmap_dir")),
|
m_langmap_dir(parSettings->as<std::string>("langmap_dir")),
|
||||||
m_plain_text(false),
|
m_plain_text(false),
|
||||||
m_syntax_highlight(true)
|
m_syntax_highlight(true)
|
||||||
|
|
|
@ -24,7 +24,11 @@
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class PastieResponse : public Response {
|
class PastieResponse : public Response {
|
||||||
public:
|
public:
|
||||||
explicit PastieResponse (const Kakoune::SafePtr<SettingsBag>& parSettings);
|
PastieResponse (
|
||||||
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual boost::string_ref page_basename() const override { return boost::string_ref("text"); }
|
virtual boost::string_ref page_basename() const override { return boost::string_ref("text"); }
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "duckhandy/stringize.h"
|
#include "duckhandy/stringize.h"
|
||||||
#include "pathname/pathname.hpp"
|
#include "pathname/pathname.hpp"
|
||||||
#include "list_highlight_langs.hpp"
|
#include "list_highlight_langs.hpp"
|
||||||
|
#include "cgi_env.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -104,14 +105,26 @@ namespace tawashi {
|
||||||
};
|
};
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
Response::Response (Types parRespType, std::string&& parValue, const Kakoune::SafePtr<SettingsBag>& parSettings, bool parWantRedis) :
|
Response::Response (
|
||||||
|
Types parRespType,
|
||||||
|
std::string&& parValue,
|
||||||
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv,
|
||||||
|
bool parWantRedis
|
||||||
|
) :
|
||||||
m_resp_value(std::move(parValue)),
|
m_resp_value(std::move(parValue)),
|
||||||
//m_page_basename(fetch_page_basename(m_cgi_env)),
|
//m_page_basename(fetch_page_basename(m_cgi_env)),
|
||||||
|
m_cgi_env(parCgiEnv),
|
||||||
m_settings(parSettings),
|
m_settings(parSettings),
|
||||||
m_website_root(make_root_path(*parSettings)),
|
m_website_root(make_root_path(*parSettings)),
|
||||||
m_resp_type(parRespType),
|
m_resp_type(parRespType),
|
||||||
|
m_stream_out(parStreamOut),
|
||||||
m_header_sent(false)
|
m_header_sent(false)
|
||||||
{
|
{
|
||||||
|
assert(m_cgi_env);
|
||||||
|
assert(m_stream_out);
|
||||||
|
|
||||||
if (parWantRedis) {
|
if (parWantRedis) {
|
||||||
m_redis = std::make_unique<redis::IncRedis>(make_incredis(*parSettings));
|
m_redis = std::make_unique<redis::IncRedis>(make_incredis(*parSettings));
|
||||||
m_redis->connect();
|
m_redis->connect();
|
||||||
|
@ -166,16 +179,16 @@ namespace tawashi {
|
||||||
switch (m_resp_type) {
|
switch (m_resp_type) {
|
||||||
case ContentType:
|
case ContentType:
|
||||||
SPDLOG_TRACE(statuslog, "Response is a Content-type (data)");
|
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;
|
break;
|
||||||
case Location:
|
case Location:
|
||||||
SPDLOG_TRACE(statuslog, "Response is a Location (redirect)");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_TRACE(statuslog, "Rendering in mustache");
|
SPDLOG_TRACE(statuslog, "Rendering in mustache");
|
||||||
std::cout << mstch::render(
|
*m_stream_out << mstch::render(
|
||||||
on_mustache_retrieve(),
|
on_mustache_retrieve(),
|
||||||
mustache_context,
|
mustache_context,
|
||||||
std::bind(
|
std::bind(
|
||||||
|
@ -187,7 +200,7 @@ namespace tawashi {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
SPDLOG_TRACE(statuslog, "Flushing output");
|
SPDLOG_TRACE(statuslog, "Flushing output");
|
||||||
std::cout.flush();
|
m_stream_out->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Response::on_mustache_retrieve() {
|
std::string Response::on_mustache_retrieve() {
|
||||||
|
@ -195,7 +208,7 @@ namespace tawashi {
|
||||||
}
|
}
|
||||||
|
|
||||||
const cgi::Env& Response::cgi_env() const {
|
const cgi::Env& Response::cgi_env() const {
|
||||||
return m_cgi_env;
|
return *m_cgi_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::change_type (Types parRespType, std::string&& parValue) {
|
void Response::change_type (Types parRespType, std::string&& parValue) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cgi_env.hpp"
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
#include "kakoune/safe_ptr.hh"
|
#include "kakoune/safe_ptr.hh"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -32,6 +31,10 @@ namespace redis {
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class SettingsBag;
|
class SettingsBag;
|
||||||
|
|
||||||
|
namespace cgi {
|
||||||
|
class Env;
|
||||||
|
} //namespace cgi
|
||||||
|
|
||||||
class Response {
|
class Response {
|
||||||
public:
|
public:
|
||||||
virtual ~Response() noexcept;
|
virtual ~Response() noexcept;
|
||||||
|
@ -48,6 +51,8 @@ namespace tawashi {
|
||||||
Types parRespType,
|
Types parRespType,
|
||||||
std::string&& parValue,
|
std::string&& parValue,
|
||||||
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv,
|
||||||
bool parWantRedis
|
bool parWantRedis
|
||||||
);
|
);
|
||||||
const cgi::Env& cgi_env() const;
|
const cgi::Env& cgi_env() const;
|
||||||
|
@ -63,12 +68,13 @@ namespace tawashi {
|
||||||
virtual void on_mustache_prepare (mstch::map& parContext);
|
virtual void on_mustache_prepare (mstch::map& parContext);
|
||||||
virtual std::string on_mustache_retrieve();
|
virtual std::string on_mustache_retrieve();
|
||||||
|
|
||||||
cgi::Env m_cgi_env;
|
|
||||||
std::string m_resp_value;
|
std::string m_resp_value;
|
||||||
|
Kakoune::SafePtr<cgi::Env> m_cgi_env;
|
||||||
Kakoune::SafePtr<SettingsBag> m_settings;
|
Kakoune::SafePtr<SettingsBag> m_settings;
|
||||||
std::string m_website_root;
|
std::string m_website_root;
|
||||||
Types m_resp_type;
|
Types m_resp_type;
|
||||||
std::unique_ptr<redis::IncRedis> m_redis;
|
std::unique_ptr<redis::IncRedis> m_redis;
|
||||||
|
std::ostream* m_stream_out;
|
||||||
bool m_header_sent;
|
bool m_header_sent;
|
||||||
};
|
};
|
||||||
} //namespace tawashi
|
} //namespace tawashi
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "response_factory.hpp"
|
#include "response_factory.hpp"
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
|
#include "cgi_env.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
@ -28,12 +29,14 @@ namespace tawashi {
|
||||||
Kakoune::SafePtr<SettingsBag> settings;
|
Kakoune::SafePtr<SettingsBag> settings;
|
||||||
boost::container::flat_map<std::string, ResponseMakerFunc> makers;
|
boost::container::flat_map<std::string, ResponseMakerFunc> makers;
|
||||||
ResponseMakerFunc jolly_maker;
|
ResponseMakerFunc jolly_maker;
|
||||||
|
Kakoune::SafePtr<cgi::Env> cgi_env;
|
||||||
};
|
};
|
||||||
|
|
||||||
ResponseFactory::ResponseFactory (const Kakoune::SafePtr<SettingsBag>& parSettings) :
|
ResponseFactory::ResponseFactory (const Kakoune::SafePtr<SettingsBag>& parSettings, const Kakoune::SafePtr<cgi::Env>& parCgiEnv) :
|
||||||
m_local_data(std::make_unique<LocalData>())
|
m_local_data(std::make_unique<LocalData>())
|
||||||
{
|
{
|
||||||
m_local_data->settings = parSettings;
|
m_local_data->settings = parSettings;
|
||||||
|
m_local_data->cgi_env = parCgiEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseFactory::~ResponseFactory() noexcept = default;
|
ResponseFactory::~ResponseFactory() noexcept = default;
|
||||||
|
@ -43,10 +46,10 @@ namespace tawashi {
|
||||||
|
|
||||||
auto maker_it = m_local_data->makers.find(std::string(parName.data(), parName.size()));
|
auto maker_it = m_local_data->makers.find(std::string(parName.data(), parName.size()));
|
||||||
if (m_local_data->makers.end() != maker_it) {
|
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) {
|
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 {
|
else {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
@ -24,11 +24,15 @@
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class SettingsBag;
|
class SettingsBag;
|
||||||
|
|
||||||
|
namespace cgi {
|
||||||
|
class Env;
|
||||||
|
} //namespace cgi
|
||||||
|
|
||||||
class ResponseFactory {
|
class ResponseFactory {
|
||||||
public:
|
public:
|
||||||
typedef std::function<std::unique_ptr<Response>(const Kakoune::SafePtr<SettingsBag>&)> ResponseMakerFunc;
|
typedef std::function<std::unique_ptr<Response>(const Kakoune::SafePtr<SettingsBag>&, const Kakoune::SafePtr<cgi::Env>& parCgiEnv)> ResponseMakerFunc;
|
||||||
|
|
||||||
explicit ResponseFactory (const Kakoune::SafePtr<SettingsBag>& parSettings);
|
explicit ResponseFactory (const Kakoune::SafePtr<SettingsBag>& parSettings, const Kakoune::SafePtr<cgi::Env>& parCgiEnv);
|
||||||
~ResponseFactory() noexcept;
|
~ResponseFactory() noexcept;
|
||||||
|
|
||||||
std::unique_ptr<Response> make_response(const boost::string_ref& parName);
|
std::unique_ptr<Response> make_response(const boost::string_ref& parName);
|
||||||
|
|
|
@ -60,8 +60,12 @@ namespace tawashi {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
SubmitPasteResponse::SubmitPasteResponse (const Kakoune::SafePtr<SettingsBag>& parSettings) :
|
SubmitPasteResponse::SubmitPasteResponse (
|
||||||
Response(Response::ContentType, "text/plain", parSettings, true)
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
) :
|
||||||
|
Response(Response::ContentType, "text/plain", parSettings, parStreamOut, parCgiEnv, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,11 @@
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class SubmitPasteResponse : public Response {
|
class SubmitPasteResponse : public Response {
|
||||||
public:
|
public:
|
||||||
explicit SubmitPasteResponse (const Kakoune::SafePtr<SettingsBag>& parSettings);
|
SubmitPasteResponse (
|
||||||
|
const Kakoune::SafePtr<SettingsBag>& parSettings,
|
||||||
|
std::ostream* parStreamOut,
|
||||||
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv
|
||||||
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual boost::string_ref page_basename() const override { return boost::string_ref("paste"); }
|
virtual boost::string_ref page_basename() const override { return boost::string_ref("paste"); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue