summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icespider/common/maybeString.h65
-rw-r--r--icespider/core/xwwwFormUrlEncoded.cpp12
-rw-r--r--icespider/core/xwwwFormUrlEncoded.h5
-rw-r--r--icespider/fcgi/cgiRequestBase.h3
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;