diff options
-rw-r--r-- | icespider/common/maybeString.h | 65 | ||||
-rw-r--r-- | icespider/core/xwwwFormUrlEncoded.cpp | 12 | ||||
-rw-r--r-- | icespider/core/xwwwFormUrlEncoded.h | 5 | ||||
-rw-r--r-- | icespider/fcgi/cgiRequestBase.h | 3 |
4 files changed, 78 insertions, 7 deletions
diff --git a/icespider/common/maybeString.h b/icespider/common/maybeString.h new file mode 100644 index 0000000..b760faa --- /dev/null +++ b/icespider/common/maybeString.h @@ -0,0 +1,65 @@ +#ifndef ICESPIDER_COMMON_MAYBESTRING_H +#define ICESPIDER_COMMON_MAYBESTRING_H + +#include <string> +#include <string_view> +#include <variant> + +namespace IceSpider { + class MaybeString { + public: + MaybeString() { } + + // NOLINTNEXTLINE(hicpp-explicit-conversions) + inline MaybeString(std::string s) : value_ {std::move(s)} { } + + // NOLINTNEXTLINE(hicpp-explicit-conversions) + inline MaybeString(std::string_view s) : value_ {std::move(s)} { } + + [[nodiscard]] inline operator std::string_view() const + { + if (value_.index() == 0) { + return std::get<0>(value_); + } + return std::get<1>(value_); + } + + [[nodiscard]] inline std::string_view + value() const + { + return *this; + } + + [[nodiscard]] inline bool + isString() const + { + return value_.index() > 0; + } + + [[nodiscard]] inline bool + operator<(const MaybeString & o) const + { + return value() < o.value(); + } + + [[nodiscard]] inline bool + operator<(const std::string_view & o) const + { + return value() < o; + } + + private: + using value_type = std::variant<std::string_view, std::string>; + value_type value_; + }; +}; + +namespace std { + inline std::ostream & + operator<<(std::ostream & s, const IceSpider::MaybeString & ms) + { + return s << ms.value(); + } +} + +#endif diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp index e594bb0..7a785bd 100644 --- a/icespider/core/xwwwFormUrlEncoded.cpp +++ b/icespider/core/xwwwFormUrlEncoded.cpp @@ -108,6 +108,7 @@ namespace IceSpider { static constexpr const std::string_view FALSE = "false"; static constexpr const std::string_view KEY = "key"; static constexpr const std::string_view VALUE = "value"; + static constexpr const std::string_view URL_ESCAPES = "%+"; XWwwFormUrlEncoded::XWwwFormUrlEncoded(std::istream & in) : input(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>()) @@ -139,7 +140,7 @@ namespace IceSpider { class SetFromString : public Slicer::ValueSource { public: - explicit SetFromString(const std::string & v) : s(v) { } + explicit SetFromString(const MaybeString & v) : s(v) { } void set(bool & t) const override @@ -176,7 +177,7 @@ namespace IceSpider { SET(Ice::Double); private: - const std::string & s; + const MaybeString & s; }; std::string @@ -219,9 +220,12 @@ namespace IceSpider { urlencoderange(std::ostream_iterator<decltype(*i)>(o), i, e); } - std::string + MaybeString XWwwFormUrlEncoded::urldecode(std::string_view::const_iterator i, std::string_view::const_iterator e) { + if (std::find_first_of(i, e, URL_ESCAPES.begin(), URL_ESCAPES.end()) == e) { + return std::string_view {i, e}; + } std::string t; t.reserve(static_cast<std::string::size_type>(std::distance(i, e))); while (i != e) { @@ -252,7 +256,7 @@ namespace IceSpider { for (; pi != decltype(pi)(); ++pi) { auto eq = std::find(pi->begin(), pi->end(), '='); if (eq == pi->end()) { - h(urldecode(pi->begin(), pi->end()), std::string()); + h(urldecode(pi->begin(), pi->end()), {}); } else { h(urldecode(pi->begin(), eq), urldecode(eq + 1, pi->end())); diff --git a/icespider/core/xwwwFormUrlEncoded.h b/icespider/core/xwwwFormUrlEncoded.h index e0f8053..6c266b6 100644 --- a/icespider/core/xwwwFormUrlEncoded.h +++ b/icespider/core/xwwwFormUrlEncoded.h @@ -2,13 +2,14 @@ #define ICESPIDER_CGI_XWWWFORMURLENCODED_H #include <boost/algorithm/string/split.hpp> +#include <maybeString.h> #include <slicer/serializer.h> #include <visibility.h> namespace IceSpider { class XWwwFormUrlEncoded : public Slicer::Deserializer { public: - using KVh = std::function<void(std::string &&, std::string &&)>; + using KVh = std::function<void(MaybeString &&, MaybeString &&)>; explicit XWwwFormUrlEncoded(std::istream & in); @@ -16,7 +17,7 @@ namespace IceSpider { DLL_PUBLIC static void iterateVars( const std::string_view & input, const KVh & h, const std::string_view & split); - DLL_PUBLIC static std::string urldecode(std::string_view::const_iterator s, std::string_view::const_iterator); + DLL_PUBLIC static MaybeString urldecode(std::string_view::const_iterator s, std::string_view::const_iterator); DLL_PUBLIC static std::string urlencode(std::string_view::const_iterator s, std::string_view::const_iterator); DLL_PUBLIC static void urlencodeto( std::ostream &, std::string_view::const_iterator s, std::string_view::const_iterator); diff --git a/icespider/fcgi/cgiRequestBase.h b/icespider/fcgi/cgiRequestBase.h index 774f06d..fdc82d7 100644 --- a/icespider/fcgi/cgiRequestBase.h +++ b/icespider/fcgi/cgiRequestBase.h @@ -5,6 +5,7 @@ #include <core.h> #include <flatMap.h> #include <ihttpRequest.h> +#include <maybeString.h> #include <string_view> namespace IceSpider { @@ -17,7 +18,7 @@ namespace IceSpider { public: using VarMap = flatmap<std::string_view, std::string_view>; using HdrMap = flatmap<std::string_view, std::string_view, AdHoc::case_less>; - using StrMap = flatmap<std::string, std::string>; + using StrMap = flatmap<MaybeString, MaybeString>; [[nodiscard]] const PathElements & getRequestPath() const override; [[nodiscard]] PathElements & getRequestPath() override; |