mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-17 10:59:39 +00:00
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:
1 parent
0ae93881b4
commit
3fe32b63b4
2 files changed
+46
-3
No files matched your search
@@ -13661,9 +13661,18 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
|
||||
|
||||
if (!query_part.empty()) {
|
||||
// Normalize the query string (decode then re-encode) while preserving
|
||||
// the original parameter order.
|
||||
auto normalized = detail::normalize_query_string(query_part);
|
||||
if (!normalized.empty()) { path_with_query += '?' + normalized; }
|
||||
// the original parameter order. When path encoding is disabled the
|
||||
// caller has supplied an already-encoded target and expects the exact
|
||||
// bytes to be sent on the wire, so skip normalization for the query
|
||||
// too. Normalizing here would decode-then-re-encode the query and
|
||||
// corrupt pre-encoded binary payloads (e.g. turning `%20` into `+`,
|
||||
// which a strict RFC 3986 server decodes back as `+`, not a space).
|
||||
if (path_encode_) {
|
||||
auto normalized = detail::normalize_query_string(query_part);
|
||||
if (!normalized.empty()) { path_with_query += '?' + normalized; }
|
||||
} else {
|
||||
path_with_query += '?' + query_part;
|
||||
}
|
||||
|
||||
// Still populate req.params for handlers/users who read them.
|
||||
detail::parse_query_text(query_part, req.params);
|
||||
|
||||
Reference in new issue
Block a user