Three ways to percent-encode
| Mode | Use it for | a b&c/d becomes |
|---|---|---|
| Component | One value going into a URL (query value, path segment) | a%20b%26c%2Fd |
| Full URL | A whole address whose separators must survive | a%20b&c/d |
| Form (+) | An application/x-www-form-urlencoded body | a+b%26c%2Fd |
The usual bug is using the full-URL mode on a value: an & inside the value is left alone and splits the parameter in two. Encode each value as a component, then join the pieces.
Decoding
Decoding turns each %XX back into a byte and reads the bytes as UTF-8. A % that is not followed by two hex digits is reported with its position. Text that was encoded twice (%2520) needs two passes: decode, put the result back in the input and decode again.
To see a complete address split into its parts, use the URL parser.