warp icon indicating copy to clipboard operation
warp copied to clipboard

GET param string gets decoded into an unrecognisable string

Open mickvandijke opened this issue 3 years ago • 1 comments

Version Warp v0.3.1

Platform Darwin MacBook-Pro.local 20.6.0 Darwin Kernel Version 20.6.0

Description I'm working on a GET endpoint using Warp, but when I receive an URL encoded query param in the form of a byte hash string (BitTorrent infohash), Warp automatically decodes this byte hash string into an unrecognisable encoding.

This is what my full request looks like:

?info_hash=%da%e7oH%e4%90%ad%c1%3f%1c%27%a7%c1%7c%7f%b9%d1%f7%16v&peer_id=-qB4380-6L2BIvAoS!-C&port=54434&uploaded=0&downloaded=0&left=0&corrupt=0&key=0DF4D289&event=started&numwant=200&compact=1&no_peer_id=1&supportcrypto=1&redundant=0

This is the struct I use to receive these params:

#[derive(Deserialize, Debug)]
pub struct HttpAnnounceRequest {
    pub downloaded: NumberOfBytes,
    pub uploaded: NumberOfBytes,
    pub key: String,
    pub peer_id: String,
    pub port: u16,
    pub info_hash: String,
    pub left: NumberOfBytes,
    pub event: String,
}

And when I debug this struct, this is what I get:

HttpAnnounceRequest { downloaded: NumberOfBytes(0), uploaded: NumberOfBytes(0), key: "0DF4D289", peer_id: "-qB4380-6L2BIvAoS!-C", port: 54434, info_hash: "��oH䐭�?\u{1c}'��|\u{7f}���\u{16}v", left: NumberOfBytes(0), event: "started" }

So I receive every param as expected, EXCEPT the "info_hash", which seems to have been decoded into some weird string. I've also tried replacing the query param struct to a Hashmap, but it showed the same weird string.

What I expected to receive in info_hash is this:

%da%e7oH%e4%90%ad%c1%3f%1c%27%a7%c1%7c%7f%b9%d1%f7%16v

But instead, I got this:

��oH䐭�?\u{1c}'��|\u{7f}���\u{16}v

I tried this code:

let announce_route =
        filters::path::path("announce")
        .and(filters::path::end())
        .and(filters::query::query())
        .map(move |query| {
            (query)
        })
        .and_then(|(query): (HttpAnnounceRequest)| {
            async move {      
                println!("{:?}", query);
                Result::<_, warp::reject::Rejection>::Ok(warp::reply::reply())
            }
        });

mickvandijke avatar Nov 21 '21 16:11 mickvandijke

Hi, yeah that is expected: warp uses serde_urlencoded on query(). You can use query::raw() and create a custom filter for your case.

jxs avatar Dec 01 '21 19:12 jxs