-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add support for custom domain name resolvers #40
base: master
Are you sure you want to change the base?
Conversation
Thanks for sending the contribution! Would you be able to provide an example how you are creating the client after these changes? I ran the tests, but most of them fail on missing type annotation for the client. When the type is annotated like this let client: restson::blocking::RestClient<dns::GaiResolver> = RestClient::new_blocking("https://httpbin.org").unwrap(); There is still an error I will look at this more closely later when I have more time, and also try to see if the explicit type annotation could be avoided altogether. This would keep the interface clean in the basic case where custom resolver is not needed. If you can provide some further feedback it is much appreciated. |
62bb80e
to
c934c0a
Compare
This allows to implement the Default trait for the GaiResolver. Using this newtype instead of hyper's GaiResolver permits to have a uniform interface where RestClient/Builder require for resolver types to implement the Default trait for internal default resolver construction.
Only provide RestClient::new and new_blocking for RestClient<GaiResolver>
Ok, the About the explicit type annotations, we made the error of assuming that rust would use the default type provided in the structs' definitions when none is specified by the user, but apparently it does not... for reasons that now escape me. The latest commits contain a proposed solution: the let rest_client = RestClient::new_blocking("https://example.org").unwrap(); Users who need a special resolver can use the builder, either setting an appropriate hyper client instance explicitely let mut http_connector = hyper::client::connect::HttpConnector::new_with_resolver(MyResolver::new());
http_connector.enforce_http(false);
let mut https_connector = hyper_tls::HttpsConnector::from((http_connector, tls_connector.into()));
https_connector.https_only(true);
let https_client = hyper::client::Client::builder()
.build(https_connector);
let mut rest_client = RestClient::builder()
.with_client(https_client)
.build("https://example.org")
.unwrap(); or by specifying the resolver type without setting an instance, in which case it will be default-constructed: let rest_client: RestClient<MyResolver> = RestClient::builder()
.build("https://example.org")
.unwrap(); This should be 99% backwards compatible, bar cases in which people have over-annotated variable types, because Let me know what you think of it |
I do like the approach taken here, and it works almost perfectly. As you mentioned, Previously this was possible let client = RestClient::builder()
.timeout(Duration::from_secs(10))
.build("https://httpbin.org")
.unwrap(); which would now have to be changed either to annotate the type let client = RestClient::<GaiResolver>::builder() or use this hacky syntax to make the compiler actually infer the default type let client = <RestClient>::builder() The first approach forces the user to over-annotate, and the second one is quite unintuitive. Sidenote about why the default type does not work here: How about also moving let builder = Builder::<MyResolver>::default();
let client = builder
.timeout(Duration::from_secs(10))
.build("https://httpbin.org")
.unwrap(); |
I actually just noticed a regression. For some reason HTTPS requests with blocking clients do not work (
Seems to be same behaviour whether the blocking client was created with The same tests pass on master, but I cannot immediately spot what is causing the issue with these changes. |
Yeah, of course... use is starting to get a bit obscure in the non-default case, but if backwards-compatibility is the main goal, I'd say it's still usable. Maybe the API can be cleaned up in a possible future (breaking) release, if the project ever ends up having one eventually.
Thank you for the link, it's been quite enlightening! (Although a bit disappointing for all the inconsistencies). The different behaviors the compiler has between type position and expression position always trip me up. Also:
that's a nice, obscure piece of syntax you got there... I think I have never seen it explicitly documented anywhere... although I guess it arises from normal path parsing rules? So no need to discuss it explicitly as its own thing in the docs, though it is quite surprising if you have never seen it before... basically it solves the issue by pushing Anyways...
That's weird, i was quite sure we had tested it. We should check again. I'll let you know when we have something new, although we are closed for summer holidays until just about the end of the month, I'll see if I can maybe take a look in my free time before then. |
I, of course, try to minimize breaking changes and keep backward compatibility when it is feasible, but I'd say it is not the main "concern" here. While quite unlikely, the new type parameter can be breaking for some already, so I will likely bump the major number anyway. My thinking is more about the fact that custom resolvers will probably be minority use case, so I would really like to keep the Unfortunately, the way the compiler handles type defaults is not very helpful here, and we need to jump through hoops to keep the syntax. Alternative approach still could be to implelement two sets of
About the obscure syntax. I think this link probably explains it better than I can! Again, thanks for the time and effort you have put in to iterating the code! And no sweat about not working on this for a while! |
We needed this feature for a commercial product, maybe it can be of use to someone else too
Cheers
-- Simone