1
0
Fork 0
mirror of https://github.com/KingDuckZ/kamokan.git synced 2025-02-13 09:33:56 +00:00

First commit

This commit is contained in:
King_DuckZ 2017-04-04 20:58:40 +01:00
commit fea5b738df
16 changed files with 315 additions and 0 deletions

6
.gitmodules vendored Normal file
View file

@ -0,0 +1,6 @@
[submodule "lib/incredis"]
path = lib/incredis
url = https://github.com/KingDuckZ/incredis.git
[submodule "lib/better-enums"]
path = lib/better-enums
url = https://github.com/aantron/better-enums

8
CMakeLists.txt Normal file
View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
project(tawashi_top)
set(TAWSHI_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
add_subdirectory(lib/incredis)
add_subdirectory(src)

1
lib/better-enums Submodule

@ -0,0 +1 @@
Subproject commit 37d8f987ca939af846a2d29a8f8198f9bf3ac4b7

1
lib/incredis Submodule

@ -0,0 +1 @@
Subproject commit ee0767e52c73402f7832bf84b2f00b36aae62c2d

24
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,24 @@
project(tawashi CXX)
find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options filesystem system)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(${PROJECT_NAME}
main.cpp
split_get_vars.cpp
response.cpp
submit_form_response.cpp
get_env.cpp
envy.cpp
)
target_include_directories(${PROJECT_NAME} SYSTEM
PRIVATE ${Boost_INCLUDE_DIRS}
PRIVATE ${TAWASHI_SOURCE_ROOT}/lib/bette-enums
)
target_link_libraries(${PROJECT_NAME}
PRIVATE ${Boost_LIBRARIES}
PRIVATE incredis
)

17
src/envy.cpp Normal file
View file

@ -0,0 +1,17 @@
#include "envy.hpp"
#include "get_env.hpp"
namespace tawashi {
std::vector<std::string> get_cgi_vars() {
using boost::string_ref;
std::vector<std::string> retlist;
retlist.reserve(CGIVars::_size());
for (CGIVars var : CGIVars::_values()) {
auto value = get_env_as<string_ref>(var._to_string(), "");
retlist.push_back(std::string(value.data(), value.size()));
}
return retlist;
}
} //namespace tawashi

29
src/envy.hpp Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include <vector>
#include <string>
#include "enum.h"
namespace tawashi {
BETTER_ENUM(CGIVars, std::size_t,
AUTH_TYPE = 0,
CONTENT_LENGTH,
CONTENT_TYPE,
GATEWAY_INTERFACE,
PATH_INFO,
PATH_TRANSLATED,
QUERY_STRING,
REMOTE_ADDR,
REMOTE_HOST,
REMOTE_IDENT,
REMOTE_USER,
REQUEST_METHOD,
SCRIPT_NAME,
SERVER_NAME,
SERVER_PORT,
SERVER_PROTOCOL,
SERVER_SOFTWARE
);
std::vector<std::string> get_cgi_vars();
} //namespace tawashi

33
src/get_env.cpp Normal file
View file

@ -0,0 +1,33 @@
#include "get_env.hpp"
#include "duckhandy/lexical_cast.hpp"
#include <cstdlib>
namespace tawashi {
boost::optional<boost::string_ref> get_env (const char* parName) {
using boost::string_ref;
using boost::make_optional;
using boost::optional;
const char* const raw_getvar = secure_getenv(parName);
return (raw_getvar ? make_optional(string_ref(raw_getvar)) : optional<string_ref>());
}
template <>
std::string get_env_as (const char* parName, const std::string& parDefault) {
auto var = get_env(parName);
return (var ? std::string(var->data(), var->size()) : parDefault);
}
template <>
boost::string_ref get_env_as (const char* parName, const boost::string_ref& parDefault) {
auto var = get_env(parName);
return (var ? *var : parDefault);
}
template <>
std::size_t get_env_as (const char* parName, const std::size_t& parDefault) {
using dhandy::lexical_cast;
auto var = get_env(parName);
return (var ? lexical_cast<std::size_t>(*var) : parDefault);
}
} //namespace tawashi

24
src/get_env.hpp Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <boost/utility/string_ref.hpp>
#include <string>
#if !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#endif
#include <cstddef>
#include <utility>
#include <boost/optional.hpp>
namespace tawashi {
boost::optional<boost::string_ref> get_env (const char* parName);
template <typename A>
A get_env_as (const char* parName, const A& parDefault);
template <>
std::string get_env_as (const char* parName, const std::string& parDefault);
template <>
boost::string_ref get_env_as (const char* parName, const boost::string_ref& parDefault);
template <>
std::size_t get_env_as (const char* parName, const std::size_t& parDefault);
} //namespace tawashi

48
src/main.cpp Normal file
View file

@ -0,0 +1,48 @@
#include "incredis/incredis.hpp"
#include "split_get_vars.hpp"
#include "submit_form_response.hpp"
#include "envy.hpp"
#include "duckhandy/lexical_cast.hpp"
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
//www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4150.pdf
namespace {
} //unnamed namespace
int main() {
using boost::string_ref;
using dhandy::lexical_cast;
std::vector<std::string> env = tawashi::get_cgi_vars();
//std::cout << "Content-type:text/plain\n\n";
const std::string& getvar = env[tawashi::CGIVars::QUERY_STRING];
//std::cout << "QUERY_STRING = \"" << getvar << "\"\n";
redis::IncRedis incredis("127.0.0.1", 6379);
tawashi::SubmitFormResponse resp;
resp.send();
for (auto& pair : tawashi::split_env_vars(getvar)) {
std::cout << "first:\t\"" << pair.first <<
"\"\tsecond:\t\"" << pair.second << "\"\n";
}
const std::size_t in_len = lexical_cast<std::size_t>(env[tawashi::CGIVars::CONTENT_LENGTH]);
std::cout << "\n<br>\n";
std::cout << "Content length: \"" << in_len << "\"\n<br>\n";
for (std::size_t z = 0; z < env.size(); ++z) {
std::cout << tawashi::CGIVars::_from_integral(z) << " = \"" << env[z] << "\"<br>\n";
}
std::string input;
if (in_len > 0)
std::copy_n(std::istream_iterator<char>(std::cin), in_len, std::back_inserter(input));
std::cout << input << '\n';
return 0;
}

17
src/response.cpp Normal file
View file

@ -0,0 +1,17 @@
#include "response.hpp"
#include <utility>
namespace tawashi {
Response::Response (std::string&& parType) :
m_content_type(std::move(parType))
{
}
Response::~Response() noexcept = default;
void Response::send() {
std::cout << "Content-type:" << m_content_type << "\n\n";
this->on_send(std::cout);
std::cout.flush();
}
} //namespace tawashi

21
src/response.hpp Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <iostream>
namespace tawashi {
class Response {
public:
virtual ~Response() noexcept;
void send();
protected:
Response (std::string&& parType);
private:
virtual void on_send (std::ostream& parStream) = 0;
std::string m_content_type;
};
} //namespace tawashi

43
src/split_get_vars.cpp Normal file
View file

@ -0,0 +1,43 @@
#include "split_get_vars.hpp"
#include <boost/algorithm/string/finder.hpp>
#include <boost/utility/string_ref.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <ciso646>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/algorithm/find.hpp>
namespace tawashi {
std::vector<std::pair<boost::string_ref, boost::string_ref>> split_env_vars (const std::string& parList) {
using MatchRange = boost::iterator_range<std::string::const_iterator>;
using boost::token_finder;
using boost::adaptors::transformed;
using boost::adaptors::filtered;
using boost::string_ref;
using boost::split_iterator;
using boost::make_iterator_range;
using boost::range::find;
//See:
//https://stackoverflow.com/questions/27999941/how-to-use-boostsplit-with-booststring-ref-in-boost-1-55
//http://www.boost.org/doc/libs/1_60_0/doc/html/boost/algorithm/token_finder.html
//https://stackoverflow.com/questions/20781090/difference-between-boostsplit-vs-boostiter-split
return boost::copy_range<std::vector<std::pair<string_ref, string_ref>>>(
make_iterator_range(
split_iterator<std::string::const_iterator>(parList, token_finder([](char c){return '&'==c;})),
split_iterator<std::string::const_iterator>()
) |
filtered([](const MatchRange& r){ return not r.empty(); }) |
transformed([](const MatchRange& r){
auto eq = find(r, '=');
if (r.empty())
return std::pair<string_ref, string_ref>();
if (r.end() == eq)
return std::make_pair(string_ref(&*r.begin(), r.size()), string_ref());
else
return std::make_pair(string_ref(&*r.begin(), eq - r.begin()), string_ref(&*(eq + 1), r.size() - (eq - r.begin() + 1)));
})
);
}
} //namespace tawashi

10
src/split_get_vars.hpp Normal file
View file

@ -0,0 +1,10 @@
#pragma once
#include "duckhandy/compatibility.h"
#include <boost/utility/string_ref.hpp>
#include <vector>
#include <utility>
namespace tawashi {
std::vector<std::pair<boost::string_ref, boost::string_ref>> split_env_vars ( const std::string& parCommaSeparatedList ) a_pure;
} //namespace tawashi

View file

@ -0,0 +1,20 @@
#include "submit_form_response.hpp"
namespace tawashi {
SubmitFormResponse::SubmitFormResponse() :
Response("text/html")
{
}
void SubmitFormResponse::on_send (std::ostream& parStream) {
parStream <<
R"(
<form action="http://127.0.0.1:8080" method="POST" accept-charset="UTF-8">
<textarea name="tawashi" cols="80" rows="24"></textarea>
<br>
<button type="submit">tawashi</button>
</br>
</form>
)";
}
} //namespace tawashi

View file

@ -0,0 +1,13 @@
#pragma once
#include "response.hpp"
namespace tawashi {
class SubmitFormResponse : public Response {
public:
SubmitFormResponse();
private:
virtual void on_send (std::ostream& parStream) override;
};
} //namespace tawashi