Query parameters and path parameters are never percent-decoded
What happens
No accessor on Request percent-decodes. Query values and path parameters are returned exactly as
they appear on the wire, so %20 never becomes a space and %3A never becomes a colon.
Measured on Robyn 0.88.0, CPython 3.12, Linux:
from robyn import Robyn, Request
app = Robyn(__file__)
@app.get("/q")
def q(request: Request):
p = request.query_params
return str({"get": p.get("v", None), "to_dict": p.to_dict(), "items": dict(p.items())})
@app.get("/p/:seg")
def p(request: Request):
return str(request.path_params["seg"])
app.start(host="127.0.0.1", port=8080)GET /q?v=a%20b
get("v", None) -> 'a%20b'
to_dict() -> {'v': ['a%20b']}
items() -> {'v': 'a%20b'}
GET /q?v=2026-01-01T00%3A00%3A00Z
get("v", None) -> '2026-01-01T00%3A00%3A00Z'
GET /p/attempt%3A1
path_params["seg"] -> 'attempt%3A1'Expected
a%20b should arrive as a b, and attempt%3A1 as attempt:1. A space is the most common
percent-encoded character in a query string, so this affects almost any client that encodes
correctly.
Where it comes from
src/types/request.rs builds the query map by splitting the raw query string on & and = and
storing the resulting substrings directly, with no decoding step. The path-parameter map is
populated the same way.
For comparison, actix-web's own web::Query extractor decodes, so this is Robyn's layer rather
than anything inherited.
Workaround
Call urllib.parse.unquote on every value at the edge of each handler.
Environment
Robyn 0.88.0 (current release at time of filing), CPython 3.12, Linux.
Source: sparckles/Robyn