diff options
Diffstat (limited to 'icespider/fcgi/cgiRequestBase.cpp')
-rw-r--r-- | icespider/fcgi/cgiRequestBase.cpp | 139 |
1 files changed, 70 insertions, 69 deletions
diff --git a/icespider/fcgi/cgiRequestBase.cpp b/icespider/fcgi/cgiRequestBase.cpp index 33fdd7b..5a07b92 100644 --- a/icespider/fcgi/cgiRequestBase.cpp +++ b/icespider/fcgi/cgiRequestBase.cpp @@ -14,7 +14,6 @@ #include <slicer/common.h> #include <slicer/modelPartsTypes.h> #include <utility> -#include <vector> namespace ba = boost::algorithm; using namespace std::literals; @@ -22,63 +21,75 @@ using namespace std::literals; #define CGI_CONST(NAME) static constexpr std::string_view NAME(#NAME) namespace IceSpider { - static const auto slash_pred = boost::algorithm::is_any_of("/"); - constexpr std::string_view amp("&"); - constexpr std::string_view semi("; "); - constexpr std::string_view HEADER_PREFIX("HTTP_"); - CGI_CONST(HTTPS); - CGI_CONST(REDIRECT_URL); - CGI_CONST(SCRIPT_NAME); - CGI_CONST(QUERY_STRING); - CGI_CONST(HTTP_COOKIE); - CGI_CONST(REQUEST_METHOD); - - template<typename in, typename out> - inline void - mapVars(const std::string_view vn, const in & envmap, out & map, const std::string_view sp) - { - auto qs = envmap.find(vn); - if (qs != envmap.end()) { - XWwwFormUrlEncoded::iterateVars( - qs->second, - [&map](auto && k, auto && v) { - map.insert({std::forward<decltype(k)>(k), std::forward<decltype(v)>(v)}); - }, - sp); + namespace { + const auto SLASH_PRED = boost::algorithm::is_any_of("/"); + constexpr std::string_view AMP("&"); + constexpr std::string_view SEMI("; "); + constexpr std::string_view HEADER_PREFIX("HTTP_"); + CGI_CONST(HTTPS); + CGI_CONST(REDIRECT_URL); + CGI_CONST(SCRIPT_NAME); + CGI_CONST(QUERY_STRING); + CGI_CONST(HTTP_COOKIE); + CGI_CONST(REQUEST_METHOD); + + template<typename In, typename Out> + inline void + mapVars(const std::string_view key, const In & envmap, Out & map, const std::string_view separators) + { + auto qs = envmap.find(key); + if (qs != envmap.end()) { + XWwwFormUrlEncoded::iterateVars( + qs->second, + [&map](auto && key, auto && value) { + map.insert({std::forward<decltype(key)>(key), std::forward<decltype(value)>(value)}); + }, + separators); + } } - } - template<typename Ex, typename Map, typename... Ks> - const std::string_view - findFirstOrElse(const Map & map, const std::string_view k, const Ks &... ks) - { - if (const auto i = map.find(k); i != map.end()) { - return i->second; + template<typename Ex, typename Map, typename... Ks> + std::string_view + findFirstOrElse(const Map & map, const std::string_view key, const Ks &... ks) + { + if (const auto iter = map.find(key); iter != map.end()) { + return iter->second; + } + if constexpr (sizeof...(ks)) { + return findFirstOrElse<Ex>(map, ks...); + } + throw Ex(); } - if constexpr (sizeof...(ks)) { - return findFirstOrElse<Ex>(map, ks...); + + template<typename Fmt, typename Map> + void + dumpMap(std::ostream & strm, const std::string_view name, const Map & map) + { + strm << name << '\n'; + for (const auto & [key, value] : map) { + Fmt::write(strm, key, value); + } } - throw Ex(); } - CgiRequestBase::CgiRequestBase(Core * c, const EnvArray envs, const EnvArray extra) : IHttpRequest(c) + CgiRequestBase::CgiRequestBase(Core * core, const EnvArray envs, const EnvArray extra) : IHttpRequest(core) { for (const auto & envdata : {envs, extra}) { - for (const std::string_view e : envdata) { - if (const auto eq = e.find('='); eq != std::string_view::npos) { - envmap.insert({e.substr(0, eq), e.substr(eq + 1)}); + for (const std::string_view env : envdata) { + if (const auto equalPos = env.find('='); equalPos != std::string_view::npos) { + envmap.emplace(env.substr(0, equalPos), env.substr(equalPos + 1)); } } } - if (auto path = findFirstOrElse<Http400_BadRequest>(envmap, REDIRECT_URL, SCRIPT_NAME).substr(1); + if (auto path = findFirstOrElse<Http400BadRequest>(envmap, REDIRECT_URL, SCRIPT_NAME).substr(1); // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) !path.empty()) { - ba::split(pathElements, path, slash_pred, ba::token_compress_off); + ba::split(pathElements, path, SLASH_PRED, ba::token_compress_off); } - mapVars(QUERY_STRING, envmap, qsmap, amp); - mapVars(HTTP_COOKIE, envmap, cookiemap, semi); + mapVars(QUERY_STRING, envmap, qsmap, AMP); + mapVars(HTTP_COOKIE, envmap, cookiemap, SEMI); for (auto header = envmap.lower_bound(HEADER_PREFIX); header != envmap.end() && ba::starts_with(header->first, HEADER_PREFIX); header++) { hdrmap.insert({header->first.substr(HEADER_PREFIX.length()), header->second}); @@ -88,38 +99,28 @@ namespace IceSpider { AdHocFormatter(VarFmt, "\t%?: [%?]\n"); AdHocFormatter(PathFmt, "\t[%?]\n"); - template<typename Fmt, typename Map> - void - dumpMap(std::ostream & s, const std::string_view n, const Map & map) - { - s << n << std::endl; - for (const auto & p : map) { - Fmt::write(s, p.first, p.second); - } - } - std::ostream & - CgiRequestBase::dump(std::ostream & s) const + CgiRequestBase::dump(std::ostream & strm) const { - dumpMap<VarFmt>(s, "Environment dump"sv, envmap); - s << "Path dump" << std::endl; - for (const auto & e : pathElements) { - PathFmt::write(s, e); + dumpMap<VarFmt>(strm, "Environment dump"sv, envmap); + strm << "Path dump" << '\n'; + for (const auto & element : pathElements) { + PathFmt::write(strm, element); } - dumpMap<VarFmt>(s, "Query string dump"sv, qsmap); - dumpMap<VarFmt>(s, "Cookie dump"sv, cookiemap); - return s; + dumpMap<VarFmt>(strm, "Query string dump"sv, qsmap); + dumpMap<VarFmt>(strm, "Cookie dump"sv, cookiemap); + return strm; } template<typename MapType> OptionalString - CgiRequestBase::optionalLookup(const std::string_view key, const MapType & vm) + CgiRequestBase::optionalLookup(const std::string_view key, const MapType & map) { - auto i = vm.find(key); - if (i == vm.end()) { + auto iter = map.find(key); + if (iter == map.end()) { return {}; } - return i->second; + return iter->second; } const PathElements & @@ -138,14 +139,14 @@ namespace IceSpider { CgiRequestBase::getRequestMethod() const { try { - auto i = envmap.find(REQUEST_METHOD); - if (i == envmap.end()) { - throw IceSpider::Http400_BadRequest(); + auto iter = envmap.find(REQUEST_METHOD); + if (iter == envmap.end()) { + throw IceSpider::Http400BadRequest(); } - return Slicer::ModelPartForEnum<HttpMethod>::lookup(i->second); + return Slicer::ModelPartForEnum<HttpMethod>::lookup(iter->second); } catch (const Slicer::InvalidEnumerationSymbol &) { - throw IceSpider::Http405_MethodNotAllowed(); + throw IceSpider::Http405MethodNotAllowed(); } } |