1

I am using warp to build a Proxy. The proxy doesn't care about parameters or path, it just delegate requests from clients. So the client may query like:

https://proxy.com/p1?a=1&b=2 or https://proxy.com/p2?c=1 or many other different paths

I want to write something like this:

    /*
    client query: https://proxy.com/test_path1?a=1
    client query: https://proxy.com/test_path2?b=2
     */
    let filter = warp::any()
        .and(warp::query::<HashMap<String, String>>())
        .map(|p: HashMap<String, String>| {
            let path = xxx.get_path();  // path = "/test_path1" or "/test_path2"
            println!("{:?}",p); // p = {"a":1} or {"b":2} respectively
        });

instead of this:

    let path1 = warp::path("test_path1").and(warp::query::<HashMap<String, String>>()).map(|p: HashMap<String,String>|{
        let path = "test_path1".to_string();
        println!("{:?}",p); // p = {"a":1} or {"b":2} respectively
    });

    let path2 = warp::path("test_path2").and(warp::query::<HashMap<String, String>>()).map(|p: HashMap<String,String>|{
        let path = "test_path2".to_string();
        println!("{:?}",p); // p = {"a":1} or {"b":2} respectively
    });

How can I do it?

YNX
  • 511
  • 6
  • 17

2 Answers2

3

Without any further detail, this does what you want by utilizing the full filter:

use warp::{self, path::FullPath, Filter};

let filter = warp::any()
    .and(warp::query::<HashMap<String, String>>())
    .and(warp::path::full())
    .map(|q: HashMap<_, _>, p: FullPath| {
        let path = p.as_str();
        format!("path: {}\nquery: {:?}", path, q)
    });
isaactfa
  • 5,461
  • 1
  • 10
  • 24
  • How do you guys find it in the document, is it there some special methodology? I was wondering. – YNX Aug 10 '22 at 16:20
  • 2
    Luckily, warp's docs are very well structured. Something like this will definitely be a filter, so I went looking in the `warp::filter` module and because it deals with the path of a request, I reckoned that it'll probably be in the `path` module. Then I just went look ing through the functions until something caught my eye, in this case "`full`: Returns the full request path, irrespective of other filters." – isaactfa Aug 10 '22 at 16:31
0

https://docs.rs/warp/latest/warp/filters/path/fn.tail.html

But are you even using warp::any? That's useful as a base to BYO (e.g. to add external data to the request) but warp::query is a filter, if you're using only that it doesn't need to be chained to anything.

And HTTP allows repeating query parameters so technically if you reify to a hashmap there is no guarantee the "proxy" will fully replicate the original request.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • "there is no guarantee the "proxy" will fully replicate the original request", does it means something like `proxy.com/path1/{int32}/{int32}?a=1`? Can you give an example? – YNX Aug 10 '22 at 16:18
  • 1
    `a=1&a=2` is a valid query string, and depending on the target can mean that `a` is a sequence of values. – Masklinn Aug 10 '22 at 19:03