1
0
Fork 0
mirror of https://github.com/KingDuckZ/kamokan.git synced 2024-11-27 00:43:47 +00:00

Implement code that splits version infos.

According to the docs, the version info is
something like LALALA/X.X with X being a single digit.
This commit is contained in:
King_DuckZ 2017-04-05 09:25:25 +01:00
parent f8d6796fc1
commit 3df7a4c5d3
4 changed files with 93 additions and 13 deletions

View file

@ -23,3 +23,6 @@ target_link_libraries(${PROJECT_NAME}
PRIVATE ${Boost_LIBRARIES}
PRIVATE incredis
)
target_compile_definitions(${PROJECT_NAME}
PRIVATE BOOST_SPIRIT_USE_PHOENIX_V3=1
)

View file

@ -1,8 +1,69 @@
#include "cgi_env.hpp"
#include "envy.hpp"
#include "duckhandy/lexical_cast.hpp"
#include <cassert>
#include <ciso646>
#include <boost/spirit/include/qi_core.hpp>
#include <boost/spirit/include/qi_numeric.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_raw.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/phoenix/object/construct.hpp>
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/phoenix/stl/container.hpp>
BOOST_FUSION_ADAPT_STRUCT(
tawashi::CGIEnv::VersionInfo,
(boost::string_ref, name)
(uint16_t, major)
(uint16_t, minor)
);
namespace tawashi {
namespace {
boost::optional<CGIEnv::VersionInfo> split_version (const std::string& parString) {
namespace px = boost::phoenix;
using boost::spirit::ascii::space;
using boost::spirit::qi::raw;
using boost::spirit::qi::char_;
using boost::spirit::qi::int_;
using boost::string_ref;
using VerNum = boost::spirit::qi::uint_parser<uint16_t, 10, 1, 1>;
using RuleType = boost::spirit::qi::rule<std::string::const_iterator, string_ref(), boost::spirit::ascii::space_type>;
using boost::spirit::_1;
using boost::spirit::qi::_val;
using boost::phoenix::begin;
using boost::phoenix::size;
using boost::phoenix::construct;
using boost::make_optional;
using boost::optional;
assert(not parString.empty());
auto beg = parString.cbegin();
RuleType protocol = raw[+(char_ - '/')][_val = px::bind(&string_ref::substr, construct<string_ref>(px::ref(parString)), begin(_1) - px::ref(beg), size(_1))];
VerNum ver_num;
auto it_curr = parString.cbegin();
CGIEnv::VersionInfo retval;
const bool parse_ret = boost::spirit::qi::phrase_parse(
it_curr,
parString.end(),
protocol >> '/' >> ver_num >> '.' >> ver_num,
space,
retval
);
if (parse_ret and parString.end() == it_curr)
return make_optional(retval);
else
return optional<CGIEnv::VersionInfo>();
}
} //unnamed namespace
CGIEnv::CGIEnv() :
m_cgi_env(get_cgi_vars())
{
@ -24,7 +85,8 @@ namespace tawashi {
return m_cgi_env[CGIVars::CONTENT_TYPE];
}
VersionInfo CGIEnv::gateway_interface() const {
auto CGIEnv::gateway_interface() const -> boost::optional<VersionInfo> {
return split_version(m_cgi_env[CGIVars::GATEWAY_INTERFACE]);
}
const std::string& CGIEnv::path_info() const {
@ -73,10 +135,19 @@ namespace tawashi {
return (value.empty() ? 0U : lexical_cast<uint16_t>(value));
}
VersionInfo CGIEnv::server_protocol() const {
auto CGIEnv::server_protocol() const -> boost::optional<VersionInfo> {
return split_version(m_cgi_env[CGIVars::SERVER_PROTOCOL]);
}
const std::string& CGIEnv::server_software() const {
return m_cgi_env[CGIVars::SERVER_SOFTWARE];
}
std::ostream& CGIEnv::print_all (std::ostream& parStream, const char* parNewline) const {
for (std::size_t z = 0; z < m_cgi_env.size(); ++z) {
parStream << CGIVars::_from_integral(z) <<
" = \"" << m_cgi_env[z] << '"' << parNewline;
}
return parStream;
}
} //namespace tawashi

View file

@ -5,23 +5,25 @@
#include <string>
#include <boost/utility/string_ref.hpp>
#include <cstdint>
#include <iostream>
#include <boost/optional.hpp>
namespace tawashi {
struct VersionInfo {
boost::string_ref name;
uint16_t major;
uint16_t minor;
};
class CGIEnv {
public:
struct VersionInfo {
boost::string_ref name;
uint16_t major;
uint16_t minor;
};
CGIEnv();
~CGIEnv() noexcept;
const std::string& auth_type() const;
std::size_t content_length() const;
const std::string& content_type() const;
VersionInfo gateway_interface() const;
boost::optional<VersionInfo> gateway_interface() const;
const std::string& path_info() const;
const std::string& path_translated() const;
KeyValueList query_string() const;
@ -33,9 +35,11 @@ namespace tawashi {
const std::string& script_name() const;
const std::string& server_name() const;
uint16_t server_port() const;
VersionInfo server_protocol() const;
boost::optional<VersionInfo> server_protocol() const;
const std::string& server_software() const;
std::ostream& print_all (std::ostream& parStream, const char* parNewline) const;
private:
std::vector<std::string> m_cgi_env;
};

View file

@ -29,13 +29,15 @@ int main() {
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";
//}
cgi_env.print_all(std::cout, "<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';
auto ver = cgi_env.gateway_interface();
if (ver)
std::cout << ver->name << " - v" << ver->major << ',' << ver->minor << "<br>\n";
return 0;
}