From d249ba682441dbb979146482aff01a7073ed165a Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Fri, 30 Jun 2023 16:04:08 -0700 Subject: [PATCH] Fix bug preventing GET params from being read on parametrized URLs. (#326) This also introduces tests to verify the bug doesn't return. The bug was due to the populate_args method checking whether the cache was empty before executing. By doing so, it was ignoring that in case of parametrized URLs, the webserver class was loading the params as arguments. Co-authored-by: Merlino --- src/http_request.cpp | 4 +++- src/httpserver/http_request.hpp | 2 ++ test/integ/basic.cpp | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/http_request.cpp b/src/http_request.cpp index 2cf152f0..342450e3 100644 --- a/src/http_request.cpp +++ b/src/http_request.cpp @@ -105,13 +105,15 @@ const http::header_view_map http_request::get_cookies() const { } void http_request::populate_args() const { - if (!cache->unescaped_args.empty()) { + if (cache->args_populated) { return; } arguments_accumulator aa; aa.unescaper = unescaper; aa.arguments = &cache->unescaped_args; MHD_get_connection_values(underlying_connection, MHD_GET_ARGUMENT_KIND, &build_request_args, reinterpret_cast(&aa)); + + cache->args_populated = true; } http_arg_value http_request::get_arg(std::string_view key) const { diff --git a/src/httpserver/http_request.hpp b/src/httpserver/http_request.hpp index 363f29ba..1281c972 100644 --- a/src/httpserver/http_request.hpp +++ b/src/httpserver/http_request.hpp @@ -410,6 +410,8 @@ class http_request { std::string requestor_ip; std::string digested_user; std::map, http::arg_comparator> unescaped_args; + + bool args_populated = false; }; std::unique_ptr cache = std::make_unique(); // Populate the data cache unescaped_args diff --git a/test/integ/basic.cpp b/test/integ/basic.cpp index 1d65add8..29c9dac8 100644 --- a/test/integ/basic.cpp +++ b/test/integ/basic.cpp @@ -948,6 +948,24 @@ LT_BEGIN_AUTO_TEST(basic_suite, regex_matching_arg) curl_easy_cleanup(curl); LT_END_AUTO_TEST(regex_matching_arg) +LT_BEGIN_AUTO_TEST(basic_suite, regex_matching_arg_with_url_pars) + args_resource resource; + LT_ASSERT_EQ(true, ws->register_resource("this/captures/{arg}/passed/in/input", &resource)); + curl_global_init(CURL_GLOBAL_ALL); + + string s; + CURL *curl = curl_easy_init(); + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/this/captures/whatever/passed/in/input?arg2=second_argument"); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); + res = curl_easy_perform(curl); + LT_ASSERT_EQ(res, 0); + LT_CHECK_EQ(s, "whateversecond_argument"); + curl_easy_cleanup(curl); +LT_END_AUTO_TEST(regex_matching_arg_with_url_pars) + LT_BEGIN_AUTO_TEST(basic_suite, regex_matching_arg_custom) args_resource resource; LT_ASSERT_EQ(true, ws->register_resource("this/captures/numeric/{arg|([0-9]+)}/passed/in/input", &resource));