http-rs / http-rs/http-types

Request.query() doesn't properly serialize vectors url encoded querys

Open
#525 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
209
Forks
91
PR merge metrics
No merged PRs in 30d

Description

# Heyo 👋

Url queries that have been url encoded are improperly cast to structs containing vectors.

Some example code for this:
```rust
#[derive(Deserialize, Debug)]
struct MultiPrintQuery {
things_to_print: Vec
}

app.at("/print").get(|req: Request<()>| async move {
let print_query: MultiPrintQuery = req.query().unwrap();
dbg!(&print_query);

for item in print_query.things_to_print {
println!("{}", item);
}

Ok(Response::new(200))
});
```

when you make a request at "/print" with non-encoded brackets the above code will work without panicking:
`curl http://127.0.0.1:8080/print?things_to_print[0]=Hello+there&things_to_print[1]=General+Kenobi`

However, when url encoded, making the same request to "/print" results in a panic:
`curl http://127.0.0.1:8080/print?things_to_print%5B0%5D=Hello+there&things_to_print%5B1%5D=General+Kenobi`

This is due to serde_qs not parsing url encoded brackets which is expected behaviour of serde_qs as it has no config specified in [request.rs](https://github.com/http-rs/http-types/blob/ac5d645ce5294554b86ebd49233d3ec01665d1d7/src/request.rs#L662C1-L662C48).
By default serde_qs runs in [strict mode](https://docs.rs/serde_qs/latest/serde_qs/index.html#strict-vs-non-strict-modes) so that url encoded brackets are not parsed the same, however serde_qs **_can_** parse url encoded brackets if strict mode is disabled in its config.

This **could** cause some issues though with some peoples existing code if the depends on using url encoded brackets in key names but im unsure that it'd affect the majority of users.

Some solutions for this are:
- Make Request.query() use Non-Strict serde_qs by default but possibly break some users existing code
- Make Request.query take a bool param for strict or not
- Keep Request.query() and make an identical one that uses non-strict serde_qs as Request.query_encoded()
- Make the user import serde_qs as a dependancy themselves and have them manually parse from req.url().query()

I'm happy to pr a fix for this but I wanted to get some input on which kind of way you guys would want to go about it or if this is even a real issue at all.

Thank you for reading this too! 🧡

Contributor guide

Open the contributing guide

Research direction

Start in request.rs at the Request.query() implementation referenced by the issue, then reproduce both curl requests to compare encoded and unencoded brackets. Read serde_qs strict and non-strict behavior before choosing an API approach. Done means vector query parameters with encoded brackets have defined, tested behavior without unintentionally breaking existing key parsing.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, backend-api-design
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.