mirror of
https://github.com/KingDuckZ/kamokan.git
synced 2025-02-13 09:33:56 +00:00
First commit
This commit is contained in:
commit
fea5b738df
16 changed files with 315 additions and 0 deletions
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal 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
8
CMakeLists.txt
Normal 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
1
lib/better-enums
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 37d8f987ca939af846a2d29a8f8198f9bf3ac4b7
|
1
lib/incredis
Submodule
1
lib/incredis
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ee0767e52c73402f7832bf84b2f00b36aae62c2d
|
24
src/CMakeLists.txt
Normal file
24
src/CMakeLists.txt
Normal 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
17
src/envy.cpp
Normal 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
29
src/envy.hpp
Normal 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
33
src/get_env.cpp
Normal 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
24
src/get_env.hpp
Normal 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
48
src/main.cpp
Normal 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
17
src/response.cpp
Normal 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
21
src/response.hpp
Normal 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
43
src/split_get_vars.cpp
Normal 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
10
src/split_get_vars.hpp
Normal 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
|
20
src/submit_form_response.cpp
Normal file
20
src/submit_form_response.cpp
Normal 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
|
13
src/submit_form_response.hpp
Normal file
13
src/submit_form_response.hpp
Normal 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
|
Loading…
Add table
Reference in a new issue