mirror of
https://github.com/KingDuckZ/kamokan.git
synced 2025-07-02 14:04:16 +00:00
Hide calls to Incredis in the Storage class.
This should allow me to write some decent simulation tests.
This commit is contained in:
parent
99e52ceb75
commit
c302dbee73
8 changed files with 214 additions and 74 deletions
|
@ -32,6 +32,7 @@ add_library(${PROJECT_NAME} STATIC
|
||||||
quick_submit_paste_response.cpp
|
quick_submit_paste_response.cpp
|
||||||
ip_utils.cpp
|
ip_utils.cpp
|
||||||
mime_split.cpp
|
mime_split.cpp
|
||||||
|
storage.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pastie_response.hpp"
|
#include "pastie_response.hpp"
|
||||||
#include "incredis/incredis.hpp"
|
#include "storage.hpp"
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
#include "escapist.hpp"
|
#include "escapist.hpp"
|
||||||
#include "cgi_env.hpp"
|
#include "cgi_env.hpp"
|
||||||
|
@ -75,13 +75,8 @@ namespace tawashi {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PastieResponse::on_mustache_prepare (mstch::map& parContext) {
|
void PastieResponse::on_mustache_prepare (mstch::map& parContext) {
|
||||||
using opt_string = redis::IncRedis::opt_string;
|
|
||||||
using opt_string_list = redis::IncRedis::opt_string_list;
|
|
||||||
|
|
||||||
boost::string_ref token = cgi_env().request_uri_relative();
|
boost::string_ref token = cgi_env().request_uri_relative();
|
||||||
auto& redis = this->redis();
|
boost::optional<std::string> pastie = this->storage().retrieve_pastie(token);
|
||||||
opt_string_list pastie_reply = redis.hmget(token, "pastie");
|
|
||||||
opt_string pastie = (pastie_reply and not pastie_reply->empty() ? (*pastie_reply)[0] : opt_string());
|
|
||||||
|
|
||||||
if (not pastie) {
|
if (not pastie) {
|
||||||
m_pastie_not_found = true;
|
m_pastie_not_found = true;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "response.hpp"
|
#include "response.hpp"
|
||||||
#include "incredis/incredis.hpp"
|
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
#include "tawashi_config.h"
|
#include "tawashi_config.h"
|
||||||
#include "duckhandy/stringize.h"
|
#include "duckhandy/stringize.h"
|
||||||
|
@ -62,23 +61,6 @@ namespace tawashi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
redis::IncRedis make_incredis (const tawashi::SettingsBag& parSettings) {
|
|
||||||
using redis::IncRedis;
|
|
||||||
|
|
||||||
if (parSettings["redis_mode"] == "inet") {
|
|
||||||
return IncRedis(
|
|
||||||
parSettings.as<std::string>("redis_server"),
|
|
||||||
parSettings.as<uint16_t>("redis_port")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (parSettings["redis_mode"] == "sock") {
|
|
||||||
return IncRedis(parSettings.as<std::string>("redis_sock"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::runtime_error("Unknown setting for \"redis_mode\", valid settings are \"inet\" or \"sock\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::string> load_whole_file (const std::string& parWebsiteRoot, const char* parSuffix, const boost::string_ref& parName, bool parThrow) {
|
boost::optional<std::string> load_whole_file (const std::string& parWebsiteRoot, const char* parSuffix, const boost::string_ref& parName, bool parThrow) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << parWebsiteRoot << parName << parSuffix;
|
oss << parWebsiteRoot << parName << parSuffix;
|
||||||
|
@ -152,6 +134,7 @@ namespace tawashi {
|
||||||
const Kakoune::SafePtr<cgi::Env>& parCgiEnv,
|
const Kakoune::SafePtr<cgi::Env>& parCgiEnv,
|
||||||
bool parWantRedis
|
bool parWantRedis
|
||||||
) :
|
) :
|
||||||
|
m_storage(parSettings),
|
||||||
//m_page_basename(fetch_page_basename(m_cgi_env)),
|
//m_page_basename(fetch_page_basename(m_cgi_env)),
|
||||||
m_cgi_env(parCgiEnv),
|
m_cgi_env(parCgiEnv),
|
||||||
m_settings(parSettings),
|
m_settings(parSettings),
|
||||||
|
@ -163,8 +146,7 @@ namespace tawashi {
|
||||||
assert(m_stream_out);
|
assert(m_stream_out);
|
||||||
|
|
||||||
if (parWantRedis) {
|
if (parWantRedis) {
|
||||||
m_redis = std::make_unique<redis::IncRedis>(make_incredis(*parSettings));
|
m_storage.connect_async();
|
||||||
m_redis->connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::config::escape = &disable_mstch_escaping;
|
mstch::config::escape = &disable_mstch_escaping;
|
||||||
|
@ -200,14 +182,7 @@ namespace tawashi {
|
||||||
{"languages", make_mstch_langmap(*m_settings)}
|
{"languages", make_mstch_langmap(*m_settings)}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_redis) {
|
m_storage.finalize_connection();
|
||||||
SPDLOG_TRACE(statuslog, "Finalizing redis connection");
|
|
||||||
m_redis->wait_for_connect();
|
|
||||||
auto batch = m_redis->make_batch();
|
|
||||||
batch.select(m_settings->as<uint32_t>("redis_db"));
|
|
||||||
batch.client_setname("tawashi_v" STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "." STRINGIZE(VERSION_PATCH));
|
|
||||||
batch.throw_if_failed();
|
|
||||||
}
|
|
||||||
|
|
||||||
SPDLOG_TRACE(statuslog, "Raising event on_process");
|
SPDLOG_TRACE(statuslog, "Raising event on_process");
|
||||||
HttpHeader http_header = this->on_process();
|
HttpHeader http_header = this->on_process();
|
||||||
|
@ -252,9 +227,9 @@ namespace tawashi {
|
||||||
return *content;
|
return *content;
|
||||||
}
|
}
|
||||||
|
|
||||||
redis::IncRedis& Response::redis() const {
|
const Storage& Response::storage() const {
|
||||||
assert(m_redis);
|
assert(m_storage.is_connected());
|
||||||
return *m_redis;
|
return m_storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SettingsBag& Response::settings() const {
|
const SettingsBag& Response::settings() const {
|
||||||
|
|
|
@ -21,15 +21,12 @@
|
||||||
#include "kakoune/safe_ptr.hh"
|
#include "kakoune/safe_ptr.hh"
|
||||||
#include "http_header.hpp"
|
#include "http_header.hpp"
|
||||||
#include "error_reasons.hpp"
|
#include "error_reasons.hpp"
|
||||||
|
#include "storage.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace redis {
|
|
||||||
class IncRedis;
|
|
||||||
} //namespace redis
|
|
||||||
|
|
||||||
namespace tawashi {
|
namespace tawashi {
|
||||||
class SettingsBag;
|
class SettingsBag;
|
||||||
|
|
||||||
|
@ -54,7 +51,7 @@ namespace tawashi {
|
||||||
const cgi::Env& cgi_env() const;
|
const cgi::Env& cgi_env() const;
|
||||||
const std::string& base_uri() const;
|
const std::string& base_uri() const;
|
||||||
virtual boost::string_ref page_basename() const = 0;
|
virtual boost::string_ref page_basename() const = 0;
|
||||||
redis::IncRedis& redis() const;
|
const Storage& storage() const;
|
||||||
const SettingsBag& settings() const;
|
const SettingsBag& settings() const;
|
||||||
virtual std::string load_mustache() const;
|
virtual std::string load_mustache() const;
|
||||||
HttpHeader make_redirect (HttpStatusCodes parCode, const std::string& parLocation);
|
HttpHeader make_redirect (HttpStatusCodes parCode, const std::string& parLocation);
|
||||||
|
@ -65,11 +62,11 @@ 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();
|
||||||
|
|
||||||
|
Storage m_storage;
|
||||||
Kakoune::SafePtr<cgi::Env> m_cgi_env;
|
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;
|
||||||
std::string m_base_uri;
|
std::string m_base_uri;
|
||||||
std::unique_ptr<redis::IncRedis> m_redis;
|
|
||||||
std::ostream* m_stream_out;
|
std::ostream* m_stream_out;
|
||||||
};
|
};
|
||||||
} //namespace tawashi
|
} //namespace tawashi
|
||||||
|
|
131
src/tawashi/storage.cpp
Normal file
131
src/tawashi/storage.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/* Copyright 2017, Michele Santullo
|
||||||
|
* This file is part of "tawashi".
|
||||||
|
*
|
||||||
|
* "tawashi" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "tawashi" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "tawashi". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "storage.hpp"
|
||||||
|
#include "settings_bag.hpp"
|
||||||
|
#include "incredis/incredis.hpp"
|
||||||
|
#include "num_to_token.hpp"
|
||||||
|
#include "tawashi_config.h"
|
||||||
|
#include "duckhandy/stringize.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <ciso646>
|
||||||
|
#include <string>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace tawashi {
|
||||||
|
namespace {
|
||||||
|
redis::IncRedis make_incredis (const SettingsBag& parSettings) {
|
||||||
|
using redis::IncRedis;
|
||||||
|
|
||||||
|
if (parSettings["redis_mode"] == "inet") {
|
||||||
|
return IncRedis(
|
||||||
|
parSettings.as<std::string>("redis_server"),
|
||||||
|
parSettings.as<uint16_t>("redis_port")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (parSettings["redis_mode"] == "sock") {
|
||||||
|
return IncRedis(parSettings.as<std::string>("redis_sock"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error("Unknown setting for \"redis_mode\", valid settings are \"inet\" or \"sock\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::SubmissionResult make_submission_result (std::string&& parToken) {
|
||||||
|
return Storage::SubmissionResult { std::move(parToken), boost::optional<ErrorReasons>() };
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::SubmissionResult make_submission_result (ErrorReasons parError) {
|
||||||
|
return Storage::SubmissionResult { std::string(), boost::make_optional(parError) };
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
Storage::Storage (const Kakoune::SafePtr<SettingsBag>& parSettings) :
|
||||||
|
m_redis(nullptr),
|
||||||
|
m_settings(parSettings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::~Storage() = default;
|
||||||
|
|
||||||
|
void Storage::connect_async() {
|
||||||
|
using redis::IncRedis;
|
||||||
|
|
||||||
|
assert(not m_redis);
|
||||||
|
m_redis = std::make_unique<redis::IncRedis>(make_incredis(*m_settings));
|
||||||
|
m_redis->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Storage::is_connected() const {
|
||||||
|
return m_redis and m_redis->is_connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Storage::finalize_connection() {
|
||||||
|
if (m_redis) {
|
||||||
|
SPDLOG_TRACE(spdlog::get("statuslog"), "Finalizing redis connection");
|
||||||
|
m_redis->wait_for_connect();
|
||||||
|
auto batch = m_redis->make_batch();
|
||||||
|
batch.select(m_settings->as<uint32_t>("redis_db"));
|
||||||
|
batch.client_setname("tawashi_v" STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "." STRINGIZE(VERSION_PATCH));
|
||||||
|
batch.throw_if_failed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::SubmissionResult Storage::submit_pastie (
|
||||||
|
const boost::string_ref& parText,
|
||||||
|
uint32_t parExpiry,
|
||||||
|
const boost::string_ref& parLang,
|
||||||
|
const std::string& parRemoteIP
|
||||||
|
) const {
|
||||||
|
if (not is_connected())
|
||||||
|
return make_submission_result(ErrorReasons::RedisDisconnected);
|
||||||
|
|
||||||
|
assert(m_redis);
|
||||||
|
auto& redis = *m_redis;
|
||||||
|
if (redis.get(parRemoteIP)) {
|
||||||
|
//please wait and submit again
|
||||||
|
return make_submission_result(ErrorReasons::UserFlooding);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto next_id = redis.incr("paste_counter");
|
||||||
|
std::string token = num_to_token(next_id);
|
||||||
|
assert(not token.empty());
|
||||||
|
if (redis.hmset(token,
|
||||||
|
"pastie", parText,
|
||||||
|
"max_ttl", dhandy::lexical_cast<std::string>(parExpiry),
|
||||||
|
"lang", parLang)
|
||||||
|
) {
|
||||||
|
redis.set(parRemoteIP, "");
|
||||||
|
redis.expire(parRemoteIP, m_settings->as<uint32_t>("resubmit_wait"));
|
||||||
|
if (redis.expire(token, parExpiry))
|
||||||
|
return make_submission_result(std::move(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_submission_result(ErrorReasons::PastieNotSaved);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::string> Storage::retrieve_pastie (const boost::string_ref& parToken) const {
|
||||||
|
using opt_string = redis::IncRedis::opt_string;
|
||||||
|
using opt_string_list = redis::IncRedis::opt_string_list;
|
||||||
|
|
||||||
|
opt_string_list pastie_reply = m_redis->hmget(parToken, "pastie");
|
||||||
|
opt_string pastie = (pastie_reply and not pastie_reply->empty() ? (*pastie_reply)[0] : opt_string());
|
||||||
|
|
||||||
|
return pastie;
|
||||||
|
}
|
||||||
|
} //namespace tawashi
|
61
src/tawashi/storage.hpp
Normal file
61
src/tawashi/storage.hpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* Copyright 2017, Michele Santullo
|
||||||
|
* This file is part of "tawashi".
|
||||||
|
*
|
||||||
|
* "tawashi" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "tawashi" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "tawashi". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "kakoune/safe_ptr.hh"
|
||||||
|
#include "error_reasons.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace redis {
|
||||||
|
class IncRedis;
|
||||||
|
} //namespace redis
|
||||||
|
|
||||||
|
namespace tawashi {
|
||||||
|
class SettingsBag;
|
||||||
|
|
||||||
|
class Storage {
|
||||||
|
public:
|
||||||
|
struct SubmissionResult {
|
||||||
|
std::string token;
|
||||||
|
boost::optional<ErrorReasons> error;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit Storage (const Kakoune::SafePtr<SettingsBag>& parSettings);
|
||||||
|
~Storage();
|
||||||
|
|
||||||
|
void connect_async();
|
||||||
|
bool is_connected() const;
|
||||||
|
void finalize_connection();
|
||||||
|
SubmissionResult submit_pastie (
|
||||||
|
const boost::string_ref& parText,
|
||||||
|
uint32_t parExpiry,
|
||||||
|
const boost::string_ref& parLang,
|
||||||
|
const std::string& parRemoteIP
|
||||||
|
) const;
|
||||||
|
|
||||||
|
boost::optional<std::string> retrieve_pastie (const boost::string_ref& parToken) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<redis::IncRedis> m_redis;
|
||||||
|
Kakoune::SafePtr<SettingsBag> m_settings;
|
||||||
|
};
|
||||||
|
} //namespace tawashi
|
|
@ -16,9 +16,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "submit_paste_response.hpp"
|
#include "submit_paste_response.hpp"
|
||||||
#include "incredis/incredis.hpp"
|
#include "storage.hpp"
|
||||||
#include "cgi_post.hpp"
|
#include "cgi_post.hpp"
|
||||||
#include "num_to_token.hpp"
|
|
||||||
#include "settings_bag.hpp"
|
#include "settings_bag.hpp"
|
||||||
#include "duckhandy/compatibility.h"
|
#include "duckhandy/compatibility.h"
|
||||||
#include "duckhandy/lexical_cast.hpp"
|
#include "duckhandy/lexical_cast.hpp"
|
||||||
|
@ -126,7 +125,7 @@ namespace tawashi {
|
||||||
//TODO: replace boost's lexical_cast with mine when I have some checks
|
//TODO: replace boost's lexical_cast with mine when I have some checks
|
||||||
//over invalid inputs
|
//over invalid inputs
|
||||||
const uint32_t duration_int = std::max(std::min((duration.empty() ? 86400U : boost::lexical_cast<uint32_t>(duration)), 2628000U), 1U);
|
const uint32_t duration_int = std::max(std::min((duration.empty() ? 86400U : boost::lexical_cast<uint32_t>(duration)), 2628000U), 1U);
|
||||||
StringOrHeader submit_result = submit_to_redis(pastie, duration_int, lang);
|
StringOrHeader submit_result = submit_to_storage(pastie, duration_int, lang);
|
||||||
const auto& token = submit_result.first;
|
const auto& token = submit_result.first;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -144,37 +143,18 @@ namespace tawashi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SubmitPasteResponse::submit_to_redis (
|
auto SubmitPasteResponse::submit_to_storage (
|
||||||
const boost::string_ref& parText,
|
const boost::string_ref& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_ref& parLang
|
const boost::string_ref& parLang
|
||||||
) -> StringOrHeader {
|
) -> StringOrHeader {
|
||||||
auto& redis = this->redis();
|
auto& storage = this->storage();
|
||||||
if (not redis.is_connected()) {
|
|
||||||
return std::make_pair(boost::optional<std::string>(), make_error_redirect(ErrorReasons::RedisDisconnected));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string remote_ip = guess_real_remote_ip(cgi_env());
|
std::string remote_ip = guess_real_remote_ip(cgi_env());
|
||||||
if (redis.get(remote_ip)) {
|
Storage::SubmissionResult submission_res = storage.submit_pastie(parText, parExpiry, parLang, remote_ip);
|
||||||
//please wait and submit again
|
if (not submission_res.error)
|
||||||
return std::make_pair(boost::optional<std::string>(), make_error_redirect(ErrorReasons::UserFlooding));
|
return std::make_pair(boost::make_optional(std::move(submission_res.token)), HttpHeader());
|
||||||
}
|
else
|
||||||
|
return std::make_pair(boost::optional<std::string>(), make_error_redirect(*submission_res.error));
|
||||||
const auto next_id = redis.incr("paste_counter");
|
|
||||||
const std::string token = num_to_token(next_id);
|
|
||||||
assert(not token.empty());
|
|
||||||
if (redis.hmset(token,
|
|
||||||
"pastie", parText,
|
|
||||||
"max_ttl", dhandy::lexical_cast<std::string>(parExpiry),
|
|
||||||
"lang", parLang)
|
|
||||||
) {
|
|
||||||
redis.set(remote_ip, "");
|
|
||||||
redis.expire(remote_ip, settings().as<uint32_t>("resubmit_wait"));
|
|
||||||
if (redis.expire(token, parExpiry))
|
|
||||||
return std::make_pair(boost::make_optional(token), HttpHeader());
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair(boost::optional<std::string>(), make_error_redirect(ErrorReasons::PastieNotSaved));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeader SubmitPasteResponse::make_success_response (std::string&& parPastieParam) {
|
HttpHeader SubmitPasteResponse::make_success_response (std::string&& parPastieParam) {
|
||||||
|
|
|
@ -41,6 +41,6 @@ namespace tawashi {
|
||||||
typedef std::pair<boost::optional<std::string>, HttpHeader> StringOrHeader;
|
typedef std::pair<boost::optional<std::string>, HttpHeader> StringOrHeader;
|
||||||
|
|
||||||
virtual HttpHeader on_process() override;
|
virtual HttpHeader on_process() override;
|
||||||
StringOrHeader submit_to_redis (const boost::string_ref& parText, uint32_t parExpiry, const boost::string_ref& parLang);
|
StringOrHeader submit_to_storage (const boost::string_ref& parText, uint32_t parExpiry, const boost::string_ref& parLang);
|
||||||
};
|
};
|
||||||
} //namespace tawashi
|
} //namespace tawashi
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue