There are (at least) two layers of specs / encodings in play here: URI and
application/x-www-form-urlencoded. The URI spec does not give any format for the query part (but restricts the valid characters). The HTML specification gives more information about queries are built by the browser to form
application/x-www-form-urlencoded POST requests or GET requests with query parameters.
The HTML 4 specification still mandates to replace spaces by
+ characters and that is also what browsers still do:
Control names and values are escaped. Space characters are replaced by
+, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by
%HH, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as “CR LF” pairs (i.e.,
HTML 5 defers to the URL spec for serializing:
Let name be the result of running percent-encode after encoding with encoding, tuple’s name, the
application/x-www-form-urlencoded percent-encode set, and true.
percent-encode after encoding has this definition:
To percent-encode after encoding, given an encoding encoding, string input, a percentEncodeSet, and a boolean spaceAsPlus, run these steps:
- Let output be the empty string.
- For each codePoint of input:
- If spaceAsPlus is true and codePoint is U+0020, then append U+002B (+) to output.
- Otherwise, run [percent-encode after encoding](https://url.spec.whatwg.org/#code-point-percent-> > encode-after-encoding) with encoding, codePoint, and percentEncodeSet, and append the result to > > output.
- Return output.
According to “and true” above
spaceAsPlus is set to true in this algorithm.
So, AFAICS, Akka HTTP does everything as specified.