From f079013b42e7bb8ba91c39d33a4a709ba1a4b9ce Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 22 Jan 2019 20:15:39 +0000 Subject: Fix-up setCookie and add urlencodeto direct to stream --- icespider/core/ihttpRequest.cpp | 19 ++++++++----------- icespider/core/ihttpRequest.h | 13 +++++++++++-- icespider/core/xwwwFormUrlEncoded.cpp | 21 +++++++++++++-------- icespider/core/xwwwFormUrlEncoded.h | 1 + 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp index cef738d..aaa0c26 100644 --- a/icespider/core/ihttpRequest.cpp +++ b/icespider/core/ihttpRequest.cpp @@ -9,6 +9,8 @@ #include namespace IceSpider { + using namespace AdHoc::literals; + IHttpRequest::IHttpRequest(const Core * c) : core(c) { @@ -129,8 +131,9 @@ namespace IceSpider { std::optional e) { std::stringstream o; - o << XWwwFormUrlEncoded::urlencode(name) << - '=' << XWwwFormUrlEncoded::urlencode(value); + XWwwFormUrlEncoded::urlencodeto(o, name.begin(), name.end()); + o << '='; + XWwwFormUrlEncoded::urlencodeto(o, value.begin(), value.end()); if (e) { char buf[45]; struct tm tm; @@ -139,9 +142,9 @@ namespace IceSpider { auto l = strftime(buf, sizeof(buf), "; expires=%a, %d %b %Y %T %Z", &tm); o.write(buf, l); } - if (d) o << "; domain=" << *d; - if (p) o << "; path=" << *p; - if (s) o << "; secure"; + if (d) "; domain=%?"_fmt(o, *d); + if (p) "; path=%?"_fmt(o, *p); + if (s) "; secure"_fmt(o); setHeader(H::SET_COOKIE, o.str()); } @@ -176,12 +179,6 @@ namespace IceSpider { } #define getParams(T) \ - template<> void IHttpRequest::setCookie(const std::string_view & n, const T & v, \ - const OptionalString & d, const OptionalString & p, \ - bool s, std::optional e) { \ - auto vs = boost::lexical_cast(v); \ - setCookie(n, std::string_view(vs), d, p, s, e); \ - } \ template<> T IHttpRequest::getURLParam(unsigned int idx) const { \ return wrapLexicalCast(getURLParam(idx)); } \ template<> std::optional IHttpRequest::getQueryStringParam(const std::string_view & key) const { \ diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index 40f02c7..5471209 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -67,8 +67,17 @@ namespace IceSpider { const OptionalString & = {}, const OptionalString & = {}, bool = false, std::optional = {}); template - void setCookie(const std::string_view &, const T &, const OptionalString & = {}, - const OptionalString & = {}, bool = false, std::optional = {}); + void setCookie(const std::string_view & n, const T & v, + const OptionalString & d, const OptionalString & p, + bool s, std::optional e) { + if constexpr (std::is_constructible::value) { + setCookie(n, std::string_view(v), d, p, s, e); + } + else { + auto vs = boost::lexical_cast(v); + setCookie(n, std::string_view(vs), d, p, s, e); + } + } template std::optional getQueryStringParam(const std::string_view & key) const; template diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp index ad68716..d050d1e 100644 --- a/icespider/core/xwwwFormUrlEncoded.cpp +++ b/icespider/core/xwwwFormUrlEncoded.cpp @@ -89,23 +89,28 @@ namespace IceSpider { std::string XWwwFormUrlEncoded::urlencode(std::string_view::const_iterator i, std::string_view::const_iterator e) { - std::string t; - t.reserve(std::distance(i, e)); + std::stringstream o; + urlencodeto(o, i, e); + return o.str(); + } + + void + XWwwFormUrlEncoded::urlencodeto(std::ostream & o, std::string_view::const_iterator i, std::string_view::const_iterator e) + { while (i != e) { if (*i == ' ') { - t += '+'; + o.put('+'); } else if (!isalnum(*i)) { - t += '%'; - t += hexchar(*i >> 4); - t += hexchar(*i & 0xf); + o.put('%'); + o.put(hexchar(*i >> 4)); + o.put(hexchar(*i & 0xf)); } else { - t += *i; + o.put(*i); } ++i; } - return t; } std::string diff --git a/icespider/core/xwwwFormUrlEncoded.h b/icespider/core/xwwwFormUrlEncoded.h index 68f6480..80042b8 100644 --- a/icespider/core/xwwwFormUrlEncoded.h +++ b/icespider/core/xwwwFormUrlEncoded.h @@ -17,6 +17,7 @@ namespace IceSpider { DLL_PUBLIC static std::string 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); DLL_PUBLIC static std::string urlencode(const std::string_view & s); private: -- cgit v1.2.3