Send query string verbatim when path encoding is disabled (#2479)

set_path_encode(false) only suppressed encoding of the path part. The
query part was always run through normalize_query_string(), which
decodes then re-encodes each key/value pair regardless of the flag.

That round-trip is lossy for pre-encoded payloads: re-encoding emits
sub-delimiters literally (%2C->",", %24->"$", %3B->";", ...) and turns
%20 into "+", which a strict RFC 3986 server decodes back as "+"
(0x2B) rather than a space (0x20), corrupting binary query data.

Honor path_encode_ for the query as well: when disabled, append the
caller-supplied query verbatim. Add a regression test asserting on the
raw request target, since the server decodes "+" as space and would
otherwise mask the difference.
This commit is contained in:
Saber Haj Rabiee
2026-07-01 21:18:05 -04:00
committed by GitHub
parent 0ae93881b4
commit 3fe32b63b4
2 changed files with 46 additions and 3 deletions
+34
View File
@@ -2929,6 +2929,40 @@ TEST(PathUrlEncodeTest, PathUrlEncode) {
}
}
TEST(PathUrlEncodeTest, PreEncodedQueryNotReencoded) {
// When path encoding is disabled the client must transmit the supplied
// query verbatim. Decoding-then-re-encoding it (the previous behavior)
// corrupts pre-encoded binary payloads: e.g. `%20` would be turned into
// `+`, which a strict RFC 3986 server decodes back as `+` (0x2B) rather
// than a space (0x20). Assert on the raw wire target to catch this.
Server svr;
const std::string expected_target = "/foo?q=a%20b%2Cc%24d%3Bx&a=%00%FF";
svr.Get("/foo", [&](const Request &req, Response &res) {
EXPECT_EQ(expected_target, req.target);
res.status = StatusCode::OK_200;
});
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);
cli.set_path_encode(false);
auto res = cli.Get(expected_target.c_str());
ASSERT_TRUE(res);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
}
TEST(PathUrlEncodeTest, IncludePercentEncodingLF) {
Server svr;