-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Remove SSL feature (and openssl/security-framework dependencies) #985
Comments
I think this is a reasonable approach. One minor nit: the -sys crates used by schannel and security-framework don't have the same limitations as openssl-sys, since they're linking to system libraries and don't need to worry about the double-link issue. |
I appreciate the forward looking nature of this issue. |
I second @drusellers , and I think this is a great idea. |
This'd also require dropping the dependency on the |
I really like this idea. I think that switching to a design that allows users to supply an I think @seanmonstar has stumbled on something that seems somewhat fundamental to crate design. If you could, it would be a huge help for other crates also using openssl directly to have a detailed reference of the changes that would be made to resolve this issue so that they can emulate the approach. |
@sfackler good point, I've now removed the cookie and solicit crates from the 0.10.x branch, since they both had optional dependencies to openssl. @zsck The excellent hyper-openssl crate documentation shows how simple it is to add in openssl 0.9 support into your crate. |
I didn't mean so much "could you explain how to add openssl support" rather "could you document the design considerations that others could follow to implement a similarly 'generic over SslClient' approach". |
I plan on making this release later today. I've tested the 0.10.x branch myself, but if anyone else wants to try it or comment about what will be released, now's the time. |
Below is the changelog currently expected for the release: Features
Breaking Changes
|
Release is done, docs up, crate published, changelog at https://github.com/hyperium/hyper/releases/tag/v0.10.0 |
Awesome, thanks for your work on this @seanmonstar! 🥇 |
The Problem
The current problem is that the openssl crate has released versions 0.9.x, and hyper is depending on 0.7.x. That by itself isn't an issue, but since the openssl crate has
openssl-sys
as a direct dependency, the old openssl version does become a problem for many people. Cargo only allows one version to exist in the whole dependency graph for any-sys
crate. So the real pain comes from when people want to use other libraries that depend on a newer version of openssl, and also depend on hyper. They are then left in a situation where their dependency graph wants bothopenssl-sys
at version 0.9.5 and 0.7.14 (versions as of this writing), and that is illegal.Attempts to Fix the Things
The suggestion so far has been that people could turn off the
ssl
feature of hyper, thus removing the openssl optional dependency. If people needed TLS, the suggestion has been to use the better client library, reqwest, which does this exact process: disableshyper/ssl
, and provides a client using rust-native-tls. hyper has always been generic over TLS implementations, thanks toSslClient
andSslServer
traits. Sounds simple, right?Well, it gets worse. Say you do exactly that: you replace your client usage with reqwest. But say you also have a server component to your app, using some other framework, such as iron, or nickel, or something newer. Those frameworks likely depend on hyper, and did not disable the
ssl
feature. So now, your dependency graph wants hyper both with and without openssl. And since reqwest (or whichever other library) also depends on openssl, but at 0.9.x, we have the conflict again. And the problem with this conflict, is that it is out of the users' control to fix it, because you cannot alter features of dependencies of dependencies.Well then, why not just upgrade openssl! Well, there are different problems with doing that. Upgrading openssl will be a breaking change, so the minor version number must increase (while hyper is 0.x, if it were 1.x, then we'd need to go up to 2.0!). Sometimes that is needed, but the cost must always be considered. Every breaking version increase for hyper has meant disruption through the ecosystem. It takes a while for all other libraries to update their internal dependency on hyper. That means a time period when trying to combine some libraries will fail, because rustc will treat the 2 different versions as completely different (as they are).
But so what, why not just upgrade this time? The problem is that every single time openssl has a breaking change, that will require hyper to also have a breaking change. So the disruption will occur to the entire hyper ecosystem each time openssl must break an API. Perhaps that slows down to a crawl at some point, and maybe we reconsider then.
Also, hey! The openssl may not be the best default dependency. In fact, rust-native-tls is probably a better default, since it works better for Windows and macOS, and fixes certificate verification on Windows. However, there's a couple downsides with using that as the default as well. First, it still depends on
-sys
crates, and young ones at that (@sfackler clarified that on Windows and macOS, there wouldn't be an issue, but there still would be on Linux), so breaking changes in those brings us back to the version bump hell mentioned above. Second, it doesn't yet expose all the things that you can currently do with openssl, such as alter verification rules, adjust cipher suites, etc. Probably fine for a default, but it means people who need those things would need to disable hyper'sssl
feature anyways, and then they run into the potentially tricky depedency graph juggling abyss that we're currently in right now.The Solution
Hm, it seems the root of the problem is having such a fundamental dependency, an http crate, depending on a
-sys
crate. So, let's rip it out! TheSslServer
andSslClient
traits will stay in, so it is still super easy to plug in some TLS. But this allows hyper to exist peacefully, while the various TLS implementations do their own thing. This allows other libraries to determine for themselves what version and even what implementation of TLS they wish to use. If you need an HTTPS client, you can use reqwest, which easily handles this upgrade (I've already checked locally). Other server frameworks can either make a choice on TLS, or they can punt the decision further up the stack, by also being generic overSslServer
.There already exists hyper-openssl, and I've reserved hyper-tls which will soon provide an excellent-for-most-people non-blocking HTTPS connector and accepter.
The 0.10.x already has this done, and it seems to work fine. I've tested that reqwest easily updates to this (it took no code changes, just a Cargo.toml change).
The text was updated successfully, but these errors were encountered: