From c2043a223bb55b9caa974d1e17d70b4d2066942f Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 11 Nov 2014 08:51:56 -0800 Subject: [PATCH] Tidy up split_commas function and use it in Server Conflicts: src/ripple/server/impl/ServerHandlerImp.cpp --- src/beast/beast/http/rfc2616.h | 74 ++++++------------- src/beast/beast/http/tests/rfc2616.test.cpp | 79 ++++++++++----------- src/ripple/server/impl/ServerHandlerImp.cpp | 4 +- 3 files changed, 61 insertions(+), 96 deletions(-) diff --git a/src/beast/beast/http/rfc2616.h b/src/beast/beast/http/rfc2616.h index 108a6517cf..fc697b8050 100644 --- a/src/beast/beast/http/rfc2616.h +++ b/src/beast/beast/http/rfc2616.h @@ -23,11 +23,10 @@ #include #include #include - +#include #include namespace beast { -namespace http { /** Routines for performing RFC2616 compliance. RFC2616: @@ -156,21 +155,23 @@ trim (std::string const& s) return trim (s); } -/** Call a functor for each comma delimited element. - Quotes and escape sequences will be parsed and converted appropriately. - Excess white space, commas, double quotes, and empty elements are not - passed to func. +/** Parse a character sequence of values separated by commas. + Double quotes and escape sequences will be converted. Excess white + space, commas, double quotes, and empty elements are not copied. Format: #(token|quoted-string) Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2 */ -template -void -for_each_element (FwdIter first, FwdIter last, Function func) +template >> +Result +split_commas(FwdIt first, FwdIt last) { - FwdIter iter (first); - std::string e; + Result result; + using string = typename Result::value_type; + FwdIt iter = first; + string e; while (iter != last) { if (*iter == '"') @@ -200,7 +201,7 @@ for_each_element (FwdIter first, FwdIter last, Function func) } if (! e.empty()) { - func (e); + result.emplace_back(std::move(e)); e.clear(); } } @@ -209,7 +210,7 @@ for_each_element (FwdIter first, FwdIter last, Function func) e = trim_right (e); if (! e.empty()) { - func (e); + result.emplace_back(std::move(e)); e.clear(); } ++iter; @@ -228,51 +229,20 @@ for_each_element (FwdIter first, FwdIter last, Function func) { e = trim_right (e); if (! e.empty()) - func (e); - } -} - -// Parse a comma-delimited list of values. -template -std::vector> -parse_csv (std::basic_string const& in, - std::ostream& log) -{ - auto first = in.cbegin(); - auto const last = in.cend(); - std::vector> result; - if (first != last) - { - static boost::regex const re( - "^" // start of line - "(?:\\s*)" // whitespace (optional) - "([a-zA-Z][_a-zA-Z0-9]*)" // identifier - "(?:\\s*)" // whitespace (optional) - "(?:,?)" // comma (optional) - "(?:\\s*)" // whitespace (optional) - , boost::regex_constants::optimize - ); - for(;;) - { - boost::smatch m; - if (! boost::regex_search(first, last, m, re, - boost::regex_constants::match_continuous)) - { - log << "Expected \n"; - throw std::exception(); - } - result.push_back(m[1]); - first = m[0].second; - if (first == last) - break; - } + result.emplace_back(std::move(e)); } return result; } +template > +Result +split_commas(std::string const& s) +{ + return split_commas(s.begin(), s.end()); +} + } // rfc2616 -} // http } // beast #endif diff --git a/src/beast/beast/http/tests/rfc2616.test.cpp b/src/beast/beast/http/tests/rfc2616.test.cpp index 83de441d5a..fd6c01c507 100644 --- a/src/beast/beast/http/tests/rfc2616.test.cpp +++ b/src/beast/beast/http/tests/rfc2616.test.cpp @@ -27,62 +27,56 @@ #include namespace beast { -namespace http { namespace rfc2616 { class rfc2616_test : public beast::unit_test::suite { public: void - check (std::string const& value, + check (std::string const& s, std::vector const& expected) { - std::vector parsed; - for_each_element (value.begin(), value.end(), - [&](std::string const& element) - { - parsed.push_back (element); - }); + auto const parsed = split_commas(s.begin(), s.end()); expect (parsed == expected); } + void test_split_commas() + { + testcase("split_commas"); + check ("", {}); + check (" ", {}); + check (" ", {}); + check ("\t", {}); + check (" \t ", {}); + check (",", {}); + check (",,", {}); + check (" ,", {}); + check (" , ,", {}); + check ("x", {"x"}); + check (" x", {"x"}); + check (" \t x", {"x"}); + check ("x ", {"x"}); + check ("x \t", {"x"}); + check (" \t x \t ", {"x"}); + check ("\"\"", {}); + check (" \"\"", {}); + check ("\"\" ", {}); + check ("\"x\"", {"x"}); + check ("\" \"", {" "}); + check ("\" x\"", {" x"}); + check ("\"x \"", {"x "}); + check ("\" x \"", {" x "}); + check ("\"\tx \"", {"\tx "}); + check ("x,y", { "x", "y" }); + check ("x ,\ty ", { "x", "y" }); + check ("x, y, z", {"x","y","z"}); + check ("x, \"y\", z", {"x","y","z"}); + } + void run() { - check ("", {}); - check (" ", {}); - check (" ", {}); - check ("\t", {}); - check (" \t ", {}); - - check (",", {}); - check (",,", {}); - check (" ,", {}); - check (" , ,", {}); - - check ("x", {"x"}); - check (" x", {"x"}); - check (" \t x", {"x"}); - check ("x ", {"x"}); - check ("x \t", {"x"}); - check (" \t x \t ", {"x"}); - - check ("\"\"", {}); - check (" \"\"", {}); - check ("\"\" ", {}); - - check ("\"x\"", {"x"}); - check ("\" \"", {" "}); - check ("\" x\"", {" x"}); - check ("\"x \"", {"x "}); - check ("\" x \"", {" x "}); - check ("\"\tx \"", {"\tx "}); - - check ("x,y", { "x", "y" }); - check ("x ,\ty ", { "x", "y" }); - - check ("x, y, z", {"x","y","z"}); - check ("x, \"y\", z", {"x","y","z"}); + test_split_commas(); } }; @@ -90,4 +84,3 @@ BEAST_DEFINE_TESTSUITE(rfc2616,http,beast); } } -} diff --git a/src/ripple/server/impl/ServerHandlerImp.cpp b/src/ripple/server/impl/ServerHandlerImp.cpp index 6926ab968e..bcb3124559 100644 --- a/src/ripple/server/impl/ServerHandlerImp.cpp +++ b/src/ripple/server/impl/ServerHandlerImp.cpp @@ -29,6 +29,7 @@ #include #include #include // +#include #include #include #include @@ -551,7 +552,8 @@ parse_Port (ParsedPort& port, Section const& section, std::ostream& log) auto const result = section.find("protocol"); if (result.second) { - for (auto const& s : parse_csv(result.first, log)) + for (auto const& s : beast::rfc2616::split_commas( + result.first.begin(), result.first.end())) port.protocol.insert(s); } }