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

[ENHANCEMENT] Add pass through features for reqwest #44

Closed
mwilliammyers opened this issue Jan 12, 2020 · 6 comments · Fixed by #68
Closed

[ENHANCEMENT] Add pass through features for reqwest #44

mwilliammyers opened this issue Jan 12, 2020 · 6 comments · Fixed by #68
Labels
enhancement New feature or request

Comments

@mwilliammyers
Copy link
Contributor

In an effort to reduce dependency duplication as reqwest is a very commonly used crate; it would be handy to have some features we can pass through to reqwest.

Some candidates are:

  • rustls-tls = ["reqwest/rustls-tls"]
  • cookies = ["reqwest/cookies"]
  • socks = ["reqwest/socks"]

Do we need the native-tls feature specifically? It looks like it adds some more features vs. default-tls? Can rustls-tls be used instead? rusttls-tls makes building a static binary via musl libc much easier...

@mwilliammyers mwilliammyers added the enhancement New feature or request label Jan 12, 2020
@russcam
Copy link
Contributor

russcam commented Jan 22, 2020

Thanks for opening @mwilliammyers. I hope you don't mind, but I have some questions about pass through features, as I'm not that familiar with this convention. Is there a good resource where I can learn more?

Is it common to allow pass through features in this manner? What are the benefits in doing so?

Some candidates are:
cookies = ["reqwest/cookies"]
socks = ["reqwest/socks"]

These features aren't needed by the client; does it make sense to also make them pass through?

Do we need the native-tls feature specifically? It looks like it adds some more features vs. default-tls? Can rustls-tls be used instead? rusttls-tls makes building a static binary via musl libc much easier...

Is rustls-tls considered a better option for consumers?

@mwilliammyers
Copy link
Contributor Author

No problem!

They are mentioned briefly in the Cargo.toml manifest format docs. There are some here for elastic-rs/elastic.

The main benefit of using them allows the end user more control over the dependencies. It is fairly common to see this feature used for popular crates, like reqwest, because it helps cargo de-duplicate dependencies. Without it, a reqwest+default-tls (with openssl) and a reqwest+rustls-tls will be compiled. You can imagine how this can end up spiraling out of control as more dependencies are added (my project has close to 300 and counting). This will most likely be pipelined so that they will built at the same time (on a multi-core machine at least) and they will probably not both end up in the resulting binary, but at the same time, it is handy to ensure a faster build by giving the end user more control over the dependencies.

rustls-tls basically just makes building a static binary much easier (which we do in production) because you don't need openssl, which can be a pain to install. Although it, nor ring which does the heavy crypto lifting, haven't been officially audited for security; they are both high quality crates and are really popular (although admittedly, they are not the default for reqwest...)

Really I am just reaching for low-hanging "nice-to-haves" 😃

@russcam
Copy link
Contributor

russcam commented Feb 28, 2020

Thanks for the links @mwilliammyers. Is there a way to specify that some dependency features are required, whilst some are optional based on being opted into through passthrough features? It's not clear to me reading the manifest format docs how this should be constructed.

For example, for the reqwest dependency, gzip and json features must always be required. In addition, I'd like to pass through a feature as default (native-tls), and then a bunch as optional (ones you've mentioned above)

[features]
default = ["native-tls"]

default-tls = ["reqwest/default-tls"]
native-tls = ["reqwest/native-tls"]
rustls-tls = ["reqwest/rustls-tls"]
cookies = ["reqwest/cookies"]
socks = ["reqwest/socks"]

[dependencies]
# required features
reqwest = { version = "^0.10", features = ["gzip", "json"  ] }

Should the reqwest dependency also specify all of the optional features, and they'll only be included if they're features opted into in elasticsearch? I think I could solve it by making gzip and json default features, but then a consumer could opt out of them, which for json at least, would break the client.

@mwilliammyers
Copy link
Contributor Author

Good question. Off the top of my head that looked correct but I wasn't 100% sure, so I used the above in a test project and it compiled just fine. When I run cargo tree --features socks, it adds in tokio-socks and its dependencies, so I think it is working as you would expect? 🤷‍♂

russcam added a commit that referenced this issue Mar 13, 2020
This commit passes through features of the reqwest dependency,
allowing end users more control over dependencies

Closes #44
russcam added a commit that referenced this issue Mar 13, 2020
This commit passes through the following features of 
the reqwest dependency:

- native-tls (enabled by default): Enables TLS functionality provided by native-tls.
    passes through to reqwest/native-tls and is set as a default feature.

- rustls-tls: Enables TLS functionality provided by rustls.
    passes through to reqwest/rustls-tls

allowing end users more control over dependencies

Attribute source code and tests
that require features of the elasticsearch package to be
enabled.

Introduce ClientCertificate enum to differentiate between
PKCS#12 archives and PEM certs, which are available
only when native-tls and rustls-tls features are enabled,
respectively.

ClientCertificate enum takes bytes representing
a certificate as opposed to a reqwest Identity because
Identity does not implement Clone, and cannot be dereferenced
from a Credentials::Certificate variant when building a Transport
because other variants are passed to the built Transport.

Closes #44
@russcam
Copy link
Contributor

russcam commented Mar 13, 2020

I've implemented native-tls and rustls-tls features in the client for now, passing through to reqwest's features and attributing in the elasticsearch source for code relying on these features.

I've been thinking about having pass-through features for the other features of reqwest, and it doesn't feel right to expose these in the client. On one hand, I can see how they could help with compilation, but on the other, the elasticsearch crate would then be exposing features of dependencies that are not relevant to the crate.

@mwilliammyers
Copy link
Contributor Author

Yeah, sounds good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants