Reqwest is nice, but it is very heavy (LoC-wise when considered with its own dependencies). In many contexts (especially security-sensitive) this is not great. Things like async support are not really needed.
Any recommendations for less-featureful, but more lightweight alternatives? Thanks for all the suggestions!
I think there aren't any alternatives. You could use hyper with a custom https connector and something like futures(-preview), but this would be quite unergonomic.
Do you know, that the new async version of reqwest supports disabling some parts of the library with features?
There’s isahc (formerly known as chttp), which is based on curl, so while it is still „heavy“ (curl is no small thing anymore), maybe it fits what’s you need?
Yeah, that's even worse, from security perspective if you ask me.
That's looks a bit better, but it will still require bringing in tokio, right? Or can I use something smaller to power the futures? I realize that async/await is trendy, but from the perspective of a lot of software that does like a handful of http request async await is just increasing the complexity.
Would some of this feedback be more constructive as Bug Reports and PRs? Even if this review is meant to be helpful it can come across as lazy and hostile to some people. I would certainly feel uncomfortable about receiving a review like this if the author did not contact me first.
Although, having read the critique, the tone is not hostile. I definitely think we need a culture of review, and that does fight with the need to be nice sometimes. When evaluating something for production the bar is pretty high. We've stuck with reqwest because it's solid, even if there's a smaller leaner crate in there somewhere wanting to come out.
I was just casually making notes and a bit in rush to go to bed, before my wife gets angry that I stay too late again. I pasted them into review, linked here and there, and was not trying to make it looks nice or mean. When reporting it did occur to me that pointing out alleged problems and mistakes is a bit uncomfortable for both me and probably the author. I would rather always write "this code is awesome", of course.
On a daily basis I review other people code, and get my code reviewed at $dayjob, and I'm used to it, and generally I have an attitude that one person never arrives at the perfect solution, and the only way forward is to always acknowledge any feedback, especially critical, and iteratively improve. But it is easier with people you know and chat face to face with. I'll definitely have to think about this for crevs purposes.
I haven't looked at the source cure, but to me it sounds like maybe some reqwest features could be made optional by putting them behind build flags, which would reduce the amount of code compiled for the minimal build.
I'm curious why you think async/await increases complexity. It is built-in to Rust, and it replaces many combinators, so the end result is that libraries are smaller and less complex, so you don't have as much code to review.
And as far as implementation goes, an async/await executor is about the same complexity as a Futures 0.1 executor.
I believe dpc is comparing async.await to a fully sync API rather than futures 0.1. If all you're using the HTTP client for is to fetch some very small number of resources over HTTP in a build script, the difference between an asynchronous backend and a synchronous one is basically nothing.
My gut feeling is that for almost any client full sync api using a threadpool is enough. A server can expect to have 10k inbound connections. A client maintaining 10k outbound connections? I'd like to hear about what are you doing there.
If the async-capable library is executor agnostic, you can use futures::block_on and/or LocalPool as an executor.
In practice, though, right now futures-0.3 experimentation is mostly assuming tokio is available. I expect that as the ecosystem matures, there will arrive a lighter "runtime" over mio to fill the niche of clients that really only need LocalPool and don't need the full tokio runtime.
(That said, there is some worth to "just using tokio", so long as you can fit it into your trust model.)
(Also, executor/reactor/runtime all of these futures bits I don't know the exact separation of concerns forgive me)
I may be a bit late to the party, but having similar requirements, I have had good experiences using attohttpc recently. I have not done a full code review, but the crate itself is quite minimal and does not contain a single unsafe block itself.