mirror of
https://github.com/KingDuckZ/kamokan.git
synced 2024-12-27 21:35:41 +00:00
Decompose the base_uri option.
This allows support for having tawashi in a subdirectory of your domain, eg http://example.com/tawashi
This commit is contained in:
parent
c5f3b3cbcc
commit
34daf8e411
9 changed files with 58 additions and 20 deletions
|
@ -2,7 +2,8 @@
|
||||||
redis_server = 127.0.0.1
|
redis_server = 127.0.0.1
|
||||||
redis_port = 6379
|
redis_port = 6379
|
||||||
redis_mode = inet
|
redis_mode = inet
|
||||||
base_uri = 127.0.0.1:8080
|
host_name = 127.0.0.1
|
||||||
|
host_port = from_downstream
|
||||||
website_root = @CMAKE_CURRENT_BINARY_DIR@/html
|
website_root = @CMAKE_CURRENT_BINARY_DIR@/html
|
||||||
logging_level = trace
|
logging_level = trace
|
||||||
log_file = @CMAKE_CURRENT_BINARY_DIR@/tawashi.log
|
log_file = @CMAKE_CURRENT_BINARY_DIR@/tawashi.log
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
redis_server = 127.0.0.1
|
redis_server = 127.0.0.1
|
||||||
redis_port = 6379
|
redis_port = 6379
|
||||||
redis_mode = inet
|
redis_mode = inet
|
||||||
base_uri = 127.0.0.1:8080
|
host_name = 127.0.0.1
|
||||||
|
host_port = from_downstream
|
||||||
website_root = html
|
website_root = html
|
||||||
logging_level = trace
|
logging_level = trace
|
||||||
|
|
|
@ -70,7 +70,9 @@ namespace {
|
||||||
parSettings.add_default("redis_mode", "sock");
|
parSettings.add_default("redis_mode", "sock");
|
||||||
parSettings.add_default("redis_sock", "/tmp/redis.sock");
|
parSettings.add_default("redis_sock", "/tmp/redis.sock");
|
||||||
parSettings.add_default("redis_db", "0");
|
parSettings.add_default("redis_db", "0");
|
||||||
parSettings.add_default("base_uri", "http://127.0.0.1");
|
parSettings.add_default("host_name", "127.0.0.1");
|
||||||
|
parSettings.add_default("host_port", "");
|
||||||
|
parSettings.add_default("host_path", "/");
|
||||||
parSettings.add_default("website_root", "");
|
parSettings.add_default("website_root", "");
|
||||||
parSettings.add_default("langmap_dir", "/usr/share/source-highlight");
|
parSettings.add_default("langmap_dir", "/usr/share/source-highlight");
|
||||||
parSettings.add_default("min_pastie_size", "10");
|
parSettings.add_default("min_pastie_size", "10");
|
||||||
|
@ -146,7 +148,7 @@ int main (int parArgc, char* parArgv[], char* parEnvp[]) {
|
||||||
SPDLOG_DEBUG(statuslog, "tawashi started");
|
SPDLOG_DEBUG(statuslog, "tawashi started");
|
||||||
statuslog->info("Loaded config: \"{}\"", config_file_path());
|
statuslog->info("Loaded config: \"{}\"", config_file_path());
|
||||||
|
|
||||||
auto cgi_env = SafeStackObject<tawashi::cgi::Env>(parEnvp);
|
auto cgi_env = SafeStackObject<tawashi::cgi::Env>(parEnvp, settings->at("host_path"));
|
||||||
tawashi::ResponseFactory resp_factory(settings, cgi_env);
|
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>);
|
||||||
|
@ -155,7 +157,7 @@ int main (int parArgc, char* parArgv[], char* parEnvp[]) {
|
||||||
resp_factory.register_maker("error.cgi", &make_response<ErrorResponse>);
|
resp_factory.register_maker("error.cgi", &make_response<ErrorResponse>);
|
||||||
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());
|
||||||
response->send();
|
response->send();
|
||||||
|
|
||||||
SPDLOG_DEBUG(statuslog, "tawashi done, quitting");
|
SPDLOG_DEBUG(statuslog, "tawashi done, quitting");
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <boost/phoenix/operator.hpp>
|
#include <boost/phoenix/operator.hpp>
|
||||||
#include <boost/fusion/adapted/struct.hpp>
|
#include <boost/fusion/adapted/struct.hpp>
|
||||||
#include <boost/phoenix/stl/container.hpp>
|
#include <boost/phoenix/stl/container.hpp>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
BOOST_FUSION_ADAPT_STRUCT(
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
tawashi::cgi::Env::VersionInfo,
|
tawashi::cgi::Env::VersionInfo,
|
||||||
|
@ -81,9 +82,16 @@ namespace cgi {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
Env::Env(const char* const* parEnvList) :
|
Env::Env(const char* const* parEnvList, const boost::string_ref& parBasePath) :
|
||||||
m_cgi_env(cgi_environment_vars(parEnvList))
|
m_cgi_env(cgi_environment_vars(parEnvList)),
|
||||||
|
m_skip_path_info(0)
|
||||||
{
|
{
|
||||||
|
const std::string& path = m_cgi_env[CGIVars::PATH_INFO];
|
||||||
|
assert(parBasePath.size() <= path.size());
|
||||||
|
if (boost::starts_with(path, parBasePath))
|
||||||
|
m_skip_path_info = parBasePath.size();
|
||||||
|
else
|
||||||
|
m_skip_path_info = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Env::~Env() noexcept = default;
|
Env::~Env() noexcept = default;
|
||||||
|
@ -106,8 +114,10 @@ namespace cgi {
|
||||||
return split_version(m_cgi_env[CGIVars::GATEWAY_INTERFACE]);
|
return split_version(m_cgi_env[CGIVars::GATEWAY_INTERFACE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Env::path_info() const {
|
boost::string_ref Env::path_info() const {
|
||||||
return m_cgi_env[CGIVars::PATH_INFO];
|
const std::string& path = m_cgi_env[CGIVars::PATH_INFO];
|
||||||
|
assert(m_skip_path_info <= path.size());
|
||||||
|
return boost::string_ref(path).substr(m_skip_path_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Env::path_translated() const {
|
const std::string& Env::path_translated() const {
|
||||||
|
|
|
@ -41,14 +41,14 @@ namespace tawashi {
|
||||||
|
|
||||||
typedef boost::container::flat_map<std::string, std::string> GetMapType;
|
typedef boost::container::flat_map<std::string, std::string> GetMapType;
|
||||||
|
|
||||||
explicit Env (const char* const* parEnvList);
|
Env (const char* const* parEnvList, const boost::string_ref& parBasePath);
|
||||||
~Env() noexcept;
|
~Env() noexcept;
|
||||||
|
|
||||||
const std::string& auth_type() const;
|
const std::string& auth_type() const;
|
||||||
std::size_t content_length() const;
|
std::size_t content_length() const;
|
||||||
const std::string& content_type() const;
|
const std::string& content_type() const;
|
||||||
boost::optional<VersionInfo> gateway_interface() const a_pure;
|
boost::optional<VersionInfo> gateway_interface() const a_pure;
|
||||||
const std::string& path_info() const;
|
boost::string_ref path_info() const;
|
||||||
const std::string& path_translated() const;
|
const std::string& path_translated() const;
|
||||||
const std::string& query_string() const;
|
const std::string& query_string() const;
|
||||||
const std::string& remote_addr() const;
|
const std::string& remote_addr() const;
|
||||||
|
@ -70,6 +70,7 @@ namespace tawashi {
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> m_cgi_env;
|
std::vector<std::string> m_cgi_env;
|
||||||
Escapist m_houdini;
|
Escapist m_houdini;
|
||||||
|
std::size_t m_skip_path_info;
|
||||||
};
|
};
|
||||||
} //namespace cgi
|
} //namespace cgi
|
||||||
} //namespace tawashi
|
} //namespace tawashi
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace tawashi {
|
||||||
using opt_string = redis::IncRedis::opt_string;
|
using opt_string = redis::IncRedis::opt_string;
|
||||||
using opt_string_list = redis::IncRedis::opt_string_list;
|
using opt_string_list = redis::IncRedis::opt_string_list;
|
||||||
|
|
||||||
auto token = boost::string_ref(cgi_env().path_info()).substr(1);
|
auto token = boost::string_ref(cgi_env().path_info());
|
||||||
auto& redis = this->redis();
|
auto& redis = this->redis();
|
||||||
opt_string_list pastie_reply = redis.hmget(token, "pastie");
|
opt_string_list pastie_reply = redis.hmget(token, "pastie");
|
||||||
opt_string pastie = (pastie_reply and not pastie_reply->empty() ? (*pastie_reply)[0] : opt_string());
|
opt_string pastie = (pastie_reply and not pastie_reply->empty() ? (*pastie_reply)[0] : opt_string());
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
#include "tawashiConfig.h"
|
#include "tawashiConfig.h"
|
||||||
#include "duckhandy/stringize.h"
|
#include "duckhandy/stringize.h"
|
||||||
|
#include "duckhandy/lexical_cast.hpp"
|
||||||
#include "pathname/pathname.hpp"
|
#include "pathname/pathname.hpp"
|
||||||
#include "list_highlight_langs.hpp"
|
#include "list_highlight_langs.hpp"
|
||||||
#include "cgi_env.hpp"
|
#include "cgi_env.hpp"
|
||||||
|
@ -107,13 +108,31 @@ namespace tawashi {
|
||||||
return parStr;
|
return parStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string make_base_uri (const boost::string_ref& parBaseURI, bool parHttps) {
|
std::string make_base_uri (const Kakoune::SafePtr<SettingsBag>& parSettings, const Kakoune::SafePtr<cgi::Env>& parCgiEnv) {
|
||||||
|
assert(parSettings);
|
||||||
|
assert(parCgiEnv);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
if (parHttps)
|
if (parCgiEnv->https())
|
||||||
oss << "https://";
|
oss << "https://";
|
||||||
else
|
else
|
||||||
oss << "http://";
|
oss << "http://";
|
||||||
oss << parBaseURI;
|
oss << parSettings->at("host_name");
|
||||||
|
boost::string_ref host_port = parSettings->at("host_port");
|
||||||
|
if (not host_port.empty()) {
|
||||||
|
if (host_port == "from_downstream") {
|
||||||
|
const uint16_t port = parCgiEnv->server_port();
|
||||||
|
if ((80 != port and not parCgiEnv->https()) or 443 != port and parCgiEnv->https()) {
|
||||||
|
oss << ':' << port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (not host_port.empty()) {
|
||||||
|
oss << ':' << host_port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boost::string_ref host_path = parSettings->at("host_path");
|
||||||
|
if (host_path != "/")
|
||||||
|
oss << host_path;
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
@ -128,7 +147,7 @@ namespace tawashi {
|
||||||
m_cgi_env(parCgiEnv),
|
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_base_uri(make_base_uri(m_settings->at("base_uri"), m_cgi_env->https())),
|
m_base_uri(make_base_uri(m_settings, m_cgi_env)),
|
||||||
m_stream_out(parStreamOut),
|
m_stream_out(parStreamOut),
|
||||||
m_header_sent(false)
|
m_header_sent(false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,7 @@ TEST_CASE ("Index response", "[index][response]") {
|
||||||
const char* const env_raw[] = {
|
const char* const env_raw[] = {
|
||||||
"AUTH_TYPE=",
|
"AUTH_TYPE=",
|
||||||
"CONTENT_TYPE=",
|
"CONTENT_TYPE=",
|
||||||
"PATH_INFO=",
|
"PATH_INFO=/",
|
||||||
"PATH_TRANSLATED=",
|
"PATH_TRANSLATED=",
|
||||||
"QUERY_STRING=index.cgi"
|
"QUERY_STRING=index.cgi"
|
||||||
"REMOTE_ADDR=",
|
"REMOTE_ADDR=",
|
||||||
|
@ -90,16 +90,19 @@ TEST_CASE ("Index response", "[index][response]") {
|
||||||
"SERVER_SOFTWARE=",
|
"SERVER_SOFTWARE=",
|
||||||
"CONTENT_LENGTH=",
|
"CONTENT_LENGTH=",
|
||||||
"SERVER_PORT=80",
|
"SERVER_PORT=80",
|
||||||
|
"HTTPS=",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
SafeStackObject<tawashi::cgi::Env> fake_env(env_raw);
|
SafeStackObject<tawashi::cgi::Env> fake_env(env_raw, "/");
|
||||||
|
|
||||||
std::string tawashi_settings(
|
std::string tawashi_settings(
|
||||||
"[tawashi]\n"
|
"[tawashi]\n"
|
||||||
" base_uri = http://127.0.0.1\n"
|
" host_name = 127.0.0.1\n"
|
||||||
" website_root = /home/michele/dev/code/cpp/tawashi/html\n"
|
" website_root = /home/michele/dev/code/cpp/tawashi/html\n"
|
||||||
" logging_level = debug\n"
|
" logging_level = debug\n"
|
||||||
" langmap_dir = /usr/share/source-highlight\n"
|
" langmap_dir = /usr/share/source-highlight\n"
|
||||||
|
" host_path = /\n"
|
||||||
|
" host_port =\n"
|
||||||
);
|
);
|
||||||
SafeStackObject<tawashi::IniFile> ini(std::move(tawashi_settings));
|
SafeStackObject<tawashi::IniFile> ini(std::move(tawashi_settings));
|
||||||
SafeStackObject<tawashi::SettingsBag> settings(ini);
|
SafeStackObject<tawashi::SettingsBag> settings(ini);
|
||||||
|
|
|
@ -49,10 +49,11 @@ TEST_CASE ("Retrieve and sanitize invalid an invalid utf-8 text", "[utf8][securi
|
||||||
|
|
||||||
const char* const fake_env[] = {
|
const char* const fake_env[] = {
|
||||||
content_length.c_str(),
|
content_length.c_str(),
|
||||||
|
"PATH_INFO=/",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
tawashi::cgi::Env env(fake_env);
|
tawashi::cgi::Env env(fake_env, "/");
|
||||||
const PostMapType& post_data = read_post(iss, env);
|
const PostMapType& post_data = read_post(iss, env);
|
||||||
|
|
||||||
CHECK(g_utf8_validate(post_data.at("invalid_text").data(), post_data.at("invalid_text").size(), nullptr));
|
CHECK(g_utf8_validate(post_data.at("invalid_text").data(), post_data.at("invalid_text").size(), nullptr));
|
||||||
|
|
Loading…
Reference in a new issue