serde_qs icon indicating copy to clipboard operation
serde_qs copied to clipboard

Encoded arrays and strict mode

Open xorxsan opened this issue 4 years ago • 2 comments
trafficstars

Hi,

I'm using tide web server to build a REST api. It internally uses http_types::Request which in turn uses serde_qs. I've a problem in which encoded arrays are not deserialized correctly in strict mode. Consider this:

#[cfg(test)]
mod test {
    #[derive(serde::Deserialize, Debug, PartialEq)]
    struct Request {
        user_ids: Vec<i32>,
    }
    #[test]
    fn serde_qs_deserializes() {
        let req = Request {
            user_ids: vec![1, 2],
        };
        assert_eq!(
            req,
            serde_qs::from_str::<Request>("user_ids%5B%5D=1&user_ids%5B%5D=2").unwrap()
        );
    }
}

I'm getting the following error:

running 1 test
test test::serde_qs_deserializes ... FAILED

failures:

---- test::serde_qs_deserializes stdout ----
thread 'test::serde_qs_deserializes' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("Multiple values for one key")'

or Custom("missing field user_ids")' if I use indexes like serde_qs::from_str::<Request>("user_ids%5B0%5D=1&user_ids%5B1%5D=2")

Is there any way to use strict mode without decoding the url (other than using loose mode)?

Thanks!

xorxsan avatar Jan 07 '21 22:01 xorxsan

Hey @xorxsan! Thanks for opening an issue.

Unfortunately yes, that would be a time where you would want to use non-strict mode. Which I imagine is not really feasible via http_types. It wouldn't solve your problem in the short term (they would still need to bump the dep), but I wonder whether strict/non-strict mode should be a cargo feature instead. That would allow you to change it via your cargo.toml instead.

Alternatively, do you have any control over the client? Can you prevent it from encoding the brackets?

samscott89 avatar Jan 08 '21 04:01 samscott89

Hi @samscott89,

thanks for your quick answer. It would be interesting to have it as a cargo feature.

I think I've control over my client (I'm using Swagger UI and that's how I got this error, but not sure I can modify it to not encode the url), but not over other potential clients. Otherwise, I'll try to get the raw query string, decode it and then parse it using serde_qs or directly parsing it in non-strict mode without decoding it. Not sure if that will decrease efficiency.

Out of curiosity, why non-strict mode is able to parse it and strict mode not? I thought encoded urls were the way to go.

Thanks!

xorxsan avatar Jan 08 '21 11:01 xorxsan