From c5a16d3ff636a96877dc570bb48672df61dfbccf Mon Sep 17 00:00:00 2001 From: qicosmos Date: Wed, 12 Jun 2024 17:52:31 +0800 Subject: [PATCH] fix url queries --- include/ylt/metric/metric.hpp | 2 +- .../ylt/standalone/cinatra/http_parser.hpp | 43 ++++++-------- src/coro_http/examples/example.cpp | 56 +++++++++++++++++++ 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/include/ylt/metric/metric.hpp b/include/ylt/metric/metric.hpp index 58d0afc5b..f93896b6c 100644 --- a/include/ylt/metric/metric.hpp +++ b/include/ylt/metric/metric.hpp @@ -131,7 +131,7 @@ struct metric_manager_t { const std::string& help, Args&&... args) { auto m = std::make_shared(name, help, std::forward(args)...); - bool r = register_metric_static(m); + bool r = register_metric_dynamic(m); if (!r) { return nullptr; } diff --git a/include/ylt/standalone/cinatra/http_parser.hpp b/include/ylt/standalone/cinatra/http_parser.hpp index 04322cee5..543198d49 100644 --- a/include/ylt/standalone/cinatra/http_parser.hpp +++ b/include/ylt/standalone/cinatra/http_parser.hpp @@ -7,6 +7,7 @@ #include #include +#include "cinatra/utils.hpp" #include "cinatra_log_wrapper.hpp" #include "define.h" #include "picohttpparser.h" @@ -225,36 +226,26 @@ class http_parser { void parse_query(std::string_view str) { std::string_view key; std::string_view val; - size_t pos = 0; - size_t length = str.length(); - for (size_t i = 0; i < length; i++) { - char c = str[i]; - if (c == '=') { - key = {&str[pos], i - pos}; - key = trim(key); - pos = i + 1; - } - else if (c == '&') { - val = {&str[pos], i - pos}; - val = trim(val); - queries_.emplace(key, val); - pos = i + 1; + auto vec = split_sv(str, "&"); + for (auto s : vec) { + if (s.empty()) { + continue; + } + size_t pos = s.find('='); + if (s.find('=') != std::string_view::npos) { + key = s.substr(0, pos); + if (key.empty()) { + continue; + } + val = s.substr(pos + 1, s.length() - pos); + } + else { + key = s; + val = ""; } - } - - if (pos == 0) { - return; - } - - if ((length - pos) > 0) { - val = {&str[pos], length - pos}; - val = trim(val); queries_.emplace(key, val); } - else if ((length - pos) == 0) { - queries_.emplace(key, ""); - } } std::string_view trim(std::string_view v) { diff --git a/src/coro_http/examples/example.cpp b/src/coro_http/examples/example.cpp index 3c8142e62..e76967395 100644 --- a/src/coro_http/examples/example.cpp +++ b/src/coro_http/examples/example.cpp @@ -289,6 +289,43 @@ struct person_t { } }; +void url_queries() { + { + http_parser parser{}; + parser.parse_query("="); + parser.parse_query("&a"); + parser.parse_query("&b="); + parser.parse_query("&c=&d"); + parser.parse_query("&e=&f=1"); + parser.parse_query("&g=1&h=1"); + auto map = parser.queries(); + assert(map["a"].empty()); + assert(map["b"].empty()); + assert(map["c"].empty()); + assert(map["d"].empty()); + assert(map["e"].empty()); + assert(map["f"] == "1"); + assert(map["g"] == "1" && map["h"] == "1"); + } + { + http_parser parser{}; + parser.parse_query("test"); + parser.parse_query("test1="); + parser.parse_query("test2=&"); + parser.parse_query("test3&"); + parser.parse_query("test4&a"); + parser.parse_query("test5&b=2"); + parser.parse_query("test6=1&c=2"); + parser.parse_query("test7=1&d"); + parser.parse_query("test8=1&e="); + parser.parse_query("test9=1&f"); + parser.parse_query("test10=1&g=10&h&i=3&j"); + auto map = parser.queries(); + assert(map["test"].empty()); + assert(map.size() == 21); + } +} + async_simple::coro::Lazy basic_usage() { coro_http_server server(1, 9001); server.set_http_handler( @@ -296,6 +333,21 @@ async_simple::coro::Lazy basic_usage() { resp.set_status_and_content(status_type::ok, "ok"); }); + server.set_http_handler( + "/queries", [](coro_http_request &req, coro_http_response &resp) { + auto map = req.get_queries(); + assert(map["test"] == ""); + resp.set_status_and_content(status_type::ok, "ok"); + }); + + server.set_http_handler( + "/queries2", [](coro_http_request &req, coro_http_response &resp) { + auto map = req.get_queries(); + assert(map["test"] == ""); + assert(map["a"] == "42"); + resp.set_status_and_content(status_type::ok, "ok"); + }); + server.set_http_handler( "/coro", [](coro_http_request &req, @@ -382,6 +434,9 @@ async_simple::coro::Lazy basic_usage() { std::cout << key << ": " << val << "\n"; } + co_await client.async_get("/queries?test"); + co_await client.async_get("/queries2?test&a=42"); + result = co_await client.async_get("/coro"); assert(result.status == 200); @@ -594,6 +649,7 @@ void coro_channel() { } int main() { + url_queries(); async_simple::coro::syncAwait(basic_usage()); async_simple::coro::syncAwait(use_aspects()); async_simple::coro::syncAwait(static_file_server());