Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dns_overrides_callback #1488

Closed

Conversation

vitalka200
Copy link

@vitalka200 vitalka200 commented Feb 28, 2022

Hi All!

I'd like to extend the DNS resolve functionality added by #1277.
It will allow dynamically updating the DNS overrides and possibly be an alternative workaround for #1421.

Having dns_overrides callback exposed, one can implement something like in the example below.

use std::net::SocketAddr;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use reqwest::Client;

struct ClientWrapper {
    client: Client,
    dns_overrides: Arc<Mutex<HashMap<String, SocketAddr>>>,
}

impl ClientWrapper {

    pub fn new() -> ClientWrapper {
        let dns_overrides: Arc<Mutex<HashMap<String, SocketAddr>>> = Arc::new(Mutex::new(HashMap::new()));
        let overrides = dns_overrides.clone();
        ClientWrapper {
            client: Client::builder().resolve_callback(move |name| {
                let overrides = overrides.lock().unwrap();
                (*overrides).get(name).cloned()
            }).build().unwrap(),
            dns_overrides
        }
    }

    pub fn new_with_predefined(overrides: HashMap<String, SocketAddr>) -> ClientWrapper {
        let dns_overrides: Arc<Mutex<HashMap<String, SocketAddr>>> = Arc::new(Mutex::new(overrides));
        let overrides = dns_overrides.clone();
        ClientWrapper {
            client: Client::builder().resolve_callback(move |name| {
                let overrides = overrides.lock().unwrap();
                (*overrides).get(name).cloned()
            }).build().unwrap(),
            dns_overrides
        }
    }

    pub fn add_resolve(&self, name: &str, addr: SocketAddr) {
        let dns_overrides = &mut self.dns_overrides.lock().unwrap();
        (*dns_overrides).insert(name.to_string(), addr);
    }

    pub fn remove_resolve(&self, name: &str) {
        let dns_overrides = &mut self.dns_overrides.lock().unwrap();
        (*dns_overrides).remove(name);
    }
}

// Predefined resolves
let wrapper = ClientWrapper::new_with_predefined([
        ("example.com".to_string(), "127.0.0.10".parse::<SocketAddr>().unwrap())
    ].iter().cloned().collect()
);

// Let's suppose that it will fail as the address is wrong
let failed_response = wrapper.client
    .get("http://example.com")
    .send()
    .await;

// So let's fix the address by replacing resolve with the correct IP
wrapper.add_resolve("example.com", "127.0.0.1".parse().unwrap());
let succeded_response = wrapper.client
.get("http://example.com")
.send()
.await;
    
// Let's remove resolve to not explode the memory
wrapper.remove_resolve("example.com");

@tasn
Copy link
Contributor

tasn commented Jul 27, 2022

Duplicate (though maybe an improvement) of #1441?

@seanmonstar, can you please take a look? We would love to have this too. 🙏🏻

@vitalka200
Copy link
Author

Implemented in #1653

@vitalka200 vitalka200 closed this Mar 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants