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

support for custom DNS resolution #1653

Merged
merged 1 commit into from Nov 2, 2022

Conversation

irrelevelephant
Copy link
Contributor

This change refactors DNS resolution, with the goal of supporting custom DNS resolvers. It addresses #1125.

Previously, reqwest defined its own HttpConnector, which dispatched to a different hyper::client::HttpConnector<R> instance depending on an enum state. This led to excess complexity in the Future type associated with the Service<Uri> implementation for the connector, which can be circumvented with a trait object.

This approach exchanges the enum for a trait object, which introduces a dynamic dispatch, but eliminates the enum match inside HttpConnector.

One annoyance is that trait objects can't make use of associated types, so the return type of the resolve function on the trait needs to be explicitly defined. Let me know what you think - happy to make changes.

Copy link
Owner

@seanmonstar seanmonstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some awesome stuff. Just a few discussions I started inline.

src/dns/mod.rs Outdated Show resolved Hide resolved
src/connect.rs Show resolved Hide resolved
src/async_impl/client.rs Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/async_impl/client.rs Outdated Show resolved Hide resolved
@seanmonstar seanmonstar merged commit f11e958 into seanmonstar:master Nov 2, 2022
@niuhuan
Copy link
Contributor

niuhuan commented Nov 15, 2022

Can you give me an example?

@irrelevelephant
Copy link
Contributor Author

@niuhuan You just need to implement the Resolve trait, then pass a trait object to the client configuration via the dns_resolver method.

A simple example of implementing the trait is the GaiResolver.

impl Resolve for GaiResolver {
    fn resolve(&self, name: Name) -> Resolving {
        let this = &mut self.0.clone();
        Box::pin(Service::<Name>::call(this, name).map(|result| {
            result
                .map(|addrs| -> Addrs { Box::new(addrs) })
                .map_err(|err| -> BoxError { Box::new(err) })
        }))
    }

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

3 participants