mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Put Params before the fragment of a client path
append_query_params() added the parameters after a '#', where the fragment, which is not sent, took them along, and write_request() read a query that came after one. Insert them before the fragment, and leave the fragment out of the query.
This commit is contained in:
1 parent
f18f0b7576
commit
079f2176af
2 files changed
+49
-4
No files matched your search
@@ -11843,9 +11843,14 @@ inline std::string sanitize_filename(const std::string &filename) {
|
|||||||
|
|
||||||
inline std::string append_query_params(const std::string &path,
|
inline std::string append_query_params(const std::string &path,
|
||||||
const Params ¶ms) {
|
const Params ¶ms) {
|
||||||
std::string path_with_query = path;
|
// The query ends at the fragment (RFC 3986 3.5), so the params go before it.
|
||||||
path_with_query += path.find('?') == std::string::npos ? '?' : '&';
|
auto fragment_pos = path.find('#');
|
||||||
|
auto path_with_query = path.substr(0, fragment_pos);
|
||||||
|
path_with_query += path_with_query.find('?') == std::string::npos ? '?' : '&';
|
||||||
path_with_query += detail::params_to_query_str(params);
|
path_with_query += detail::params_to_query_str(params);
|
||||||
|
if (fragment_pos != std::string::npos) {
|
||||||
|
path_with_query.append(path, fragment_pos, std::string::npos);
|
||||||
|
}
|
||||||
return path_with_query;
|
return path_with_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16370,10 +16375,12 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
|
|||||||
// `encode_request_target`; the raw query is still needed here to decide
|
// `encode_request_target`; the raw query is still needed here to decide
|
||||||
// between populating `req.params` from it and falling back to building a
|
// between populating `req.params` from it and falling back to building a
|
||||||
// query out of caller-supplied `req.params`.
|
// query out of caller-supplied `req.params`.
|
||||||
auto query_pos = req.path.find('?');
|
// The fragment, which is not sent, is not part of the query.
|
||||||
|
auto target = req.path.substr(0, req.path.find('#'));
|
||||||
|
auto query_pos = target.find('?');
|
||||||
auto query_part = query_pos == std::string::npos
|
auto query_part = query_pos == std::string::npos
|
||||||
? std::string()
|
? std::string()
|
||||||
: req.path.substr(query_pos + 1);
|
: target.substr(query_pos + 1);
|
||||||
|
|
||||||
auto path_with_query =
|
auto path_with_query =
|
||||||
detail::encode_request_target(req.path, path_encode_);
|
detail::encode_request_target(req.path, path_encode_);
|
||||||
|
|||||||
@@ -5812,6 +5812,44 @@ TEST(URLFragmentTest, WithFragment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(URLFragmentTest, ParamsGoBeforeTheFragment) {
|
||||||
|
EXPECT_EQ("/a?b=1#f", append_query_params("/a#f", {{"b", "1"}}));
|
||||||
|
EXPECT_EQ("/a?q=0&b=1#f", append_query_params("/a?q=0#f", {{"b", "1"}}));
|
||||||
|
|
||||||
|
Server svr;
|
||||||
|
std::vector<std::string> targets;
|
||||||
|
svr.Get("/hi", [&](const Request &req, Response & /*res*/) {
|
||||||
|
targets.push_back(req.target);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto thread = std::thread([&]() { svr.listen(HOST, PORT); });
|
||||||
|
auto se = detail::scope_exit([&] {
|
||||||
|
svr.stop();
|
||||||
|
thread.join();
|
||||||
|
ASSERT_FALSE(svr.is_running());
|
||||||
|
});
|
||||||
|
|
||||||
|
svr.wait_until_ready();
|
||||||
|
|
||||||
|
Client cli(HOST, PORT);
|
||||||
|
EXPECT_TRUE(cli.Get("/hi#f", Params{{"a", "1"}}, Headers{}));
|
||||||
|
EXPECT_TRUE(cli.Get("/hi?q=0#f", Params{{"a", "1"}}, Headers{}));
|
||||||
|
EXPECT_TRUE(cli.open_stream("GET", "/hi#f", {{"a", "1"}}).is_valid());
|
||||||
|
|
||||||
|
// A '?' after the '#' belongs to the fragment, not to the query.
|
||||||
|
Request req;
|
||||||
|
req.method = "GET";
|
||||||
|
req.path = "/hi#f?x=1";
|
||||||
|
req.params.emplace("a", "1");
|
||||||
|
Response res;
|
||||||
|
auto error = Error::Success;
|
||||||
|
EXPECT_TRUE(cli.send(req, res, error));
|
||||||
|
|
||||||
|
EXPECT_EQ((std::vector<std::string>{"/hi?a=1", "/hi?q=0&a=1", "/hi?a=1",
|
||||||
|
"/hi?a=1"}),
|
||||||
|
targets);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(HeaderWriter, SetHeaderWriter) {
|
TEST(HeaderWriter, SetHeaderWriter) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user