@@ -2178,6 +2178,16 @@ void read_file(const std::string &path, std::string &out);
21782178
21792179std::string trim_copy (const std::string &s);
21802180
2181+ void divide (
2182+ const char *data, std::size_t size, char d,
2183+ std::function<void (const char *, std::size_t , const char *, std::size_t )>
2184+ fn);
2185+
2186+ void divide (
2187+ const std::string &str, char d,
2188+ std::function<void (const char *, std::size_t , const char *, std::size_t )>
2189+ fn);
2190+
21812191void split (const char *b, const char *e, char d,
21822192 std::function<void (const char *, const char *)> fn);
21832193
@@ -2201,6 +2211,8 @@ const char *get_header_value(const Headers &headers, const std::string &key,
22012211
22022212std::string params_to_query_str (const Params ¶ms);
22032213
2214+ void parse_query_text (const char *data, std::size_t size, Params ¶ms);
2215+
22042216void parse_query_text (const std::string &s, Params ¶ms);
22052217
22062218bool parse_multipart_boundary (const std::string &content_type,
@@ -2669,6 +2681,27 @@ inline std::string trim_double_quotes_copy(const std::string &s) {
26692681 return s;
26702682}
26712683
2684+ inline void
2685+ divide (const char *data, std::size_t size, char d,
2686+ std::function<void (const char *, std::size_t , const char *, std::size_t )>
2687+ fn) {
2688+ const auto it = std::find (data, data + size, d);
2689+ const auto found = static_cast <std::size_t >(it != data + size);
2690+ const auto lhs_data = data;
2691+ const auto lhs_size = static_cast <std::size_t >(it - data);
2692+ const auto rhs_data = it + found;
2693+ const auto rhs_size = size - lhs_size - found;
2694+
2695+ fn (lhs_data, lhs_size, rhs_data, rhs_size);
2696+ }
2697+
2698+ inline void
2699+ divide (const std::string &str, char d,
2700+ std::function<void (const char *, std::size_t , const char *, std::size_t )>
2701+ fn) {
2702+ divide (str.data (), str.size (), d, std::move (fn));
2703+ }
2704+
26722705inline void split (const char *b, const char *e, char d,
26732706 std::function<void (const char *, const char *)> fn) {
26742707 return split (b, e, d, (std::numeric_limits<size_t >::max)(), std::move (fn));
@@ -4392,29 +4425,33 @@ inline std::string params_to_query_str(const Params ¶ms) {
43924425 return query;
43934426}
43944427
4395- inline void parse_query_text (const std::string &s, Params ¶ms) {
4428+ inline void parse_query_text (const char *data, std::size_t size,
4429+ Params ¶ms) {
43964430 std::set<std::string> cache;
4397- split (s. data (), s. data () + s. size () , ' &' , [&](const char *b, const char *e) {
4431+ split (data, data + size, ' &' , [&](const char *b, const char *e) {
43984432 std::string kv (b, e);
43994433 if (cache.find (kv) != cache.end ()) { return ; }
4400- cache.insert (kv );
4434+ cache.insert (std::move (kv) );
44014435
44024436 std::string key;
44034437 std::string val;
4404- split (b, e, ' =' , [&](const char *b2, const char *e2 ) {
4405- if (key.empty ()) {
4406- key.assign (b2, e2 );
4407- } else {
4408- val.assign (b2, e2 );
4409- }
4410- });
4438+ divide (b, static_cast <std::size_t >(e - b), ' =' ,
4439+ [&](const char *lhs_data, std::size_t lhs_size, const char *rhs_data,
4440+ std::size_t rhs_size) {
4441+ key.assign (lhs_data, lhs_size);
4442+ val.assign (rhs_data, rhs_size);
4443+ });
44114444
44124445 if (!key.empty ()) {
44134446 params.emplace (decode_url (key, true ), decode_url (val, true ));
44144447 }
44154448 });
44164449}
44174450
4451+ inline void parse_query_text (const std::string &s, Params ¶ms) {
4452+ parse_query_text (s.data (), s.size (), params);
4453+ }
4454+
44184455inline bool parse_multipart_boundary (const std::string &content_type,
44194456 std::string &boundary) {
44204457 auto boundary_keyword = " boundary=" ;
@@ -6072,26 +6109,13 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
60726109 }
60736110 }
60746111
6075- size_t count = 0 ;
6076-
6077- detail::split (req.target .data (), req.target .data () + req.target .size (), ' ?' ,
6078- 2 , [&](const char *b, const char *e) {
6079- switch (count) {
6080- case 0 :
6081- req.path = detail::decode_url (std::string (b, e), false );
6082- break ;
6083- case 1 : {
6084- if (e - b > 0 ) {
6085- detail::parse_query_text (std::string (b, e), req.params );
6086- }
6087- break ;
6088- }
6089- default : break ;
6090- }
6091- count++;
6092- });
6093-
6094- if (count > 2 ) { return false ; }
6112+ detail::divide (req.target , ' ?' ,
6113+ [&](const char *lhs_data, std::size_t lhs_size,
6114+ const char *rhs_data, std::size_t rhs_size) {
6115+ req.path = detail::decode_url (
6116+ std::string (lhs_data, lhs_size), false );
6117+ detail::parse_query_text (rhs_data, rhs_size, req.params );
6118+ });
60956119 }
60966120
60976121 return true ;
0 commit comments