proxy: allow setting dynamic headers at intercept time
My main use case here is to set a short-lived Proxy-Authorization Bearer auth token and dynamic trace id on a proxy connection.
To support this, the callback in Proxy::custom needs to be able to return auth/headers alongside a Url.
I've packaged the auth/headers as ProxyExtra (formerly Extra), which is now part of the public API.
Preserving backwards compat needed some minor trait contortions. Technically there's a new Sized trait bound on IntoProxy, but this should be OK, since I'm not sure how you would impl the trait for an unsized type anyway. Existing callers should not need to change anything.
We've been running a (hacky) version of this patch for ~2 years. I just finally got around to cleaning this up so it's suitable for upstreaming : )
Thanks for the PR! I'm curious about your use case, would you need it to be something that runs with custom, or would it be better if you could configure details on the RequestBuilder? (The meta one is https://github.com/seanmonstar/reqwest/issues/2641, but people have asked about proxy specifically.)
Sure, you can see how we're using an older version here: https://github.com/lexe-app/lexe-public/blob/master/app-rs/src/client.rs#L300
The Proxy::custom callback picks up the most recent Bearer auth token that it needs to send to the proxy.
Before making a request, you call self.ensure_authed().await? to ensure you have an unexpired token:
impl Client {
async fn node_info(&self) -> Result<NodeInfo, NodeApiError> {
self.ensure_authed().await?;
let run_url = &self.run_url;
let url = format!("{run_url}/app/node_info");
let req = self.run_rest.get(url, &Empty {});
self.run_rest.send(req).await
}
}
A per-request proxy config might also work (as long as the connection pooling continues to work):
impl Client {
async fn node_info(&self) -> Result<NodeInfo, NodeApiError> {
let url = format!("{run_url}/app/node_info");
let token = self.ensure_authed().await?;
let proxy = Proxy::all(self.gateway_url).custom_http_auth(token)?;
let req = self
.run_rest
.get(url, &Empty {})
.proxy(proxy);
self.run_rest.send(req).await
}
}