From bfec6fffb4acd9673ecf066a0e4f1b4baf2dd831 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 25 Dec 2017 08:37:54 +0300 Subject: Make use of butl url encode() and decode() functions --- web/apache/request.cxx | 27 ++++++---- web/mime-url-encoding.cxx | 124 +++++++++++----------------------------------- web/mime-url-encoding.hxx | 23 +++++---- 3 files changed, 57 insertions(+), 117 deletions(-) (limited to 'web') diff --git a/web/apache/request.cxx b/web/apache/request.cxx index 3393555..51590e3 100644 --- a/web/apache/request.cxx +++ b/web/apache/request.cxx @@ -18,7 +18,6 @@ #include // unique_ptr #include #include -#include #include #include #include // str*(), memcpy(), size_t @@ -353,7 +352,7 @@ namespace web { if (path_.empty ()) { - path_ = path_type (rec_->uri); + path_ = path_type (rec_->uri); // Is already URL-decoded. // Module request handler can not be called if URI is empty. // @@ -514,10 +513,9 @@ namespace web { assert (!buffer); // Cookie buffering is not implemented yet. - ostringstream s; - mime_url_encode (name, s); - s << "="; - mime_url_encode (value, s); + string s (mime_url_encode (name)); + s += "="; + s += mime_url_encode (value); if (max_age) { @@ -528,20 +526,27 @@ namespace web // char b[100]; strftime (b, sizeof (b), "%a, %d-%b-%Y %H:%M:%S GMT", gmtime (&t)); - s << "; Expires=" << b; + s += "; Expires="; + s += b; } if (path) - s << ";Path=" << path; + { + s += ";Path="; + s += path; + } if (domain) - s << ";Domain=" << domain; + { + s += ";Domain="; + s += domain; + } if (secure) - s << ";Secure"; + s += ";Secure"; state (request_state::headers); - apr_table_add (rec_->err_headers_out, "Set-Cookie", s.str ().c_str ()); + apr_table_add (rec_->err_headers_out, "Set-Cookie", s.c_str ()); } void request:: diff --git a/web/mime-url-encoding.cxx b/web/mime-url-encoding.cxx index e0022bc..00f8852 100644 --- a/web/mime-url-encoding.cxx +++ b/web/mime-url-encoding.cxx @@ -4,132 +4,64 @@ #include -#include // hex, uppercase, right #include -#include // setw(), setfill() -#include -#include -#include // size_t, strspn() -#include // invalid_argument +#include // back_inserter + +#include using namespace std; +using namespace butl; namespace web { - // Encode characters different from unreserved ones specified in - // "2.3. Unreserved Characters" of http://tools.ietf.org/html/rfc3986. - // - void - mime_url_encode (const char* v, ostream& o) + inline static bool + encode_query (char& c) { - char f (o.fill ()); - ostream::fmtflags g (o.flags ()); - o << hex << uppercase << right << setfill ('0'); - - char c; - while ((c = *v++) != '\0') + if (c == ' ') { - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9')) - { - o << c; - } - else - { - switch (c) - { - case ' ': o << '+'; break; - case '.': - case '_': - case '-': - case '~': o << c; break; - default: - { - o << "%" << setw (2) << static_cast (c); - break; - } - } - } + c = '+'; + return false; } - o.flags (g); - o.fill (f); + return !url::unreserved (c); } string - mime_url_encode (const char* v) + mime_url_encode (const char* v, bool query) { - stringstream o; - mime_url_encode (v, o); - return o.str (); + return query ? url::encode (v, encode_query) : url::encode (v); } string - mime_url_encode (const string& v) + mime_url_encode (const string& v, bool query) { - return mime_url_encode (v.c_str ()); + return query ? url::encode (v, encode_query) : url::encode (v); } string - mime_url_decode (const char* b, const char* e, bool trim) + mime_url_decode (const char* b, const char* e, bool trim, bool query) { if (trim) { - b += strspn (b, " "); + for (; b != e && *b == ' '; ++b) ; - if (b >= e) + if (b == e) return string (); while (*--e == ' '); ++e; } - string value; - value.reserve (e - b); - - char bf[3]; - bf[2] = '\0'; - - while (b != e) - { - char c (*b++); - switch (c) - { - case '+': - { - value.append (" "); - break; - } - case '%': - { - if (*b == '\0' || b[1] == '\0') - { - throw invalid_argument ("::web::mime_url_decode short"); - } - - *bf = *b; - bf[1] = b[1]; - - char* ebf (nullptr); - size_t vl (strtoul (bf, &ebf, 16)); - - if (*ebf != '\0') - { - throw invalid_argument ("::web::mime_url_decode wrong"); - } - - value.append (1, static_cast (vl)); - b += 2; - break; - } - default: - { - value.append (1, c); - break; - } - } - } - - return value; + string r; + if (!query) + url::decode (b, e, back_inserter (r)); + else + url::decode (b, e, back_inserter (r), + [] (char& c) + { + if (c == '+') + c = ' '; + }); + return r; } } diff --git a/web/mime-url-encoding.hxx b/web/mime-url-encoding.hxx index d45f4ca..f748738 100644 --- a/web/mime-url-encoding.hxx +++ b/web/mime-url-encoding.hxx @@ -6,25 +6,28 @@ #define WEB_MIME_URL_ENCODING_HXX #include -#include namespace web { - // @@ Add the query flag (true by default). If true, then the encoding is - // applied to the URL query part, and so the plus character is used to - // encode the space character. Audit use cases afterwards. + // URL-encode characters other than unreserved (see RFC3986). If the query + // flag is true, then the encoding is applied to the URL query part, and so + // convert space characters to plus characters rather than percent-encode + // them. // - void - mime_url_encode (const char* v, std::ostream& o); - std::string - mime_url_encode (const char* v); + mime_url_encode (const char*, bool query = true); std::string - mime_url_encode (const std::string& v); + mime_url_encode (const std::string&, bool query = true); + // If the query flag is true, then convert plus characters to space + // characters (see above). Throw std::invalid_argument if an invalid encoding + // sequence is encountered. + // std::string - mime_url_decode (const char* b, const char* e, bool trim = false); + mime_url_decode (const char* b, const char* e, + bool trim = false, + bool query = true); } #endif // WEB_MIME_URL_ENCODING_HXX -- cgit v1.1