mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 01:39:28 +02:00
feat: add configurable TLS backend selection with native-tls as default (#1541)
Add support for choosing between native-tls and rustls-tls backends through feature flags, with native-tls as the default for maximum platform compatibility. Key changes: - Add mutually exclusive native-tls and rustls-tls feature flags - Use conditional compilation to select TLS implementation - Configure rustls-tls with platform certificate verifier - Refactor to workspace-based dependency management - Update CI workflows with improved cross-compilation support - Add comprehensive TLS backend documentation The native-tls backend uses system TLS libraries (OpenSSL on Linux, Secure Transport on macOS, SChannel on Windows) while rustls-tls provides a pure Rust implementation with platform certificate stores.
This commit is contained in:
parent
03bcdc6bda
commit
0a4969ffe2
31 changed files with 928 additions and 577 deletions
|
@ -1,27 +1,43 @@
|
|||
[package]
|
||||
name = "librespot-core"
|
||||
version = "0.6.0-dev"
|
||||
version.workspace = true
|
||||
rust-version.workspace = true
|
||||
authors = ["Paul Lietar <paul@lietar.net>"]
|
||||
build = "build.rs"
|
||||
license.workspace = true
|
||||
description = "The core functionality provided by librespot"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/librespot-org/librespot"
|
||||
edition = "2021"
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies.librespot-oauth]
|
||||
path = "../oauth"
|
||||
version = "0.6.0-dev"
|
||||
[features]
|
||||
# Refer to the workspace Cargo.toml for the list of features
|
||||
default = ["native-tls"]
|
||||
|
||||
[dependencies.librespot-protocol]
|
||||
path = "../protocol"
|
||||
version = "0.6.0-dev"
|
||||
# TLS backends (mutually exclusive - see oauth/src/lib.rs for compile-time checks)
|
||||
# Note: Validation is in oauth since it's compiled first in the dependency tree.
|
||||
native-tls = [
|
||||
"dep:hyper-tls",
|
||||
"hyper-proxy2/tls",
|
||||
"librespot-oauth/native-tls",
|
||||
"tokio-tungstenite/native-tls",
|
||||
]
|
||||
rustls-tls = [
|
||||
"dep:hyper-rustls",
|
||||
"hyper-proxy2/rustls",
|
||||
"librespot-oauth/rustls-tls",
|
||||
"tokio-tungstenite/__rustls-tls",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
librespot-oauth.workspace = true
|
||||
librespot-protocol.workspace = true
|
||||
|
||||
aes = "0.8"
|
||||
base64 = "0.22"
|
||||
byteorder = "1.5"
|
||||
bytes = "1"
|
||||
data-encoding = "2.9"
|
||||
flate2 = "1.1"
|
||||
form_urlencoded = "1.2"
|
||||
futures-core = "0.3"
|
||||
futures-util = { version = "0.3", features = [
|
||||
|
@ -37,9 +53,22 @@ governor = { version = "0.10", default-features = false, features = [
|
|||
hmac = "0.12"
|
||||
httparse = "1.10"
|
||||
http = "1.3"
|
||||
hyper = { version = "1.6", features = ["http1", "http2"] }
|
||||
hyper-util = { version = "0.1", features = ["client"] }
|
||||
http-body-util = "0.1"
|
||||
hyper = { version = "1.6", features = ["http1", "http2"] }
|
||||
hyper-proxy2 = { version = "0.1", default-features = false }
|
||||
hyper-rustls = { version = "0.27", default-features = false, features = [
|
||||
"http1",
|
||||
"http2",
|
||||
"ring",
|
||||
"rustls-platform-verifier",
|
||||
"tls12",
|
||||
], optional = true }
|
||||
hyper-tls = { version = "0.6", optional = true }
|
||||
hyper-util = { version = "0.1", default-features = false, features = [
|
||||
"client",
|
||||
"http1",
|
||||
"http2",
|
||||
] }
|
||||
log = "0.4"
|
||||
nonzero_ext = "0.3"
|
||||
num-bigint = "0.4"
|
||||
|
@ -51,6 +80,7 @@ pbkdf2 = { version = "0.12", default-features = false, features = ["hmac"] }
|
|||
pin-project-lite = "0.2"
|
||||
priority-queue = "2.5"
|
||||
protobuf = "3.7"
|
||||
protobuf-json-mapping = "3.7"
|
||||
quick-xml = { version = "0.38", features = ["serialize"] }
|
||||
rand = "0.9"
|
||||
rsa = "0.9"
|
||||
|
@ -71,28 +101,10 @@ tokio = { version = "1", features = [
|
|||
"time",
|
||||
] }
|
||||
tokio-stream = "0.1"
|
||||
tokio-tungstenite = { version = "0.27", default-features = false }
|
||||
tokio-util = { version = "0.7", features = ["codec"] }
|
||||
url = "2"
|
||||
uuid = { version = "1", default-features = false, features = ["v4"] }
|
||||
data-encoding = "2.9"
|
||||
flate2 = "1.1"
|
||||
protobuf-json-mapping = "3.7"
|
||||
rustls = { version = "0.23", default-features = false, features = ["ring"] }
|
||||
|
||||
hyper-proxy2 = { version = "0.1", default-features = false, features = [
|
||||
"rustls-webpki",
|
||||
] }
|
||||
hyper-rustls = { version = "0.27", default-features = false, features = [
|
||||
"ring",
|
||||
"http1",
|
||||
"logging",
|
||||
"tls12",
|
||||
"webpki-tokio",
|
||||
"http2",
|
||||
] }
|
||||
tokio-tungstenite = { version = "0.27", default-features = false, features = [
|
||||
"rustls-tls-webpki-roots",
|
||||
] }
|
||||
|
||||
[build-dependencies]
|
||||
rand = "0.9"
|
||||
|
|
|
@ -13,7 +13,6 @@ use http::{Uri, header::HeaderValue};
|
|||
use http_body_util::{BodyExt, Full};
|
||||
use hyper::{HeaderMap, Request, Response, StatusCode, body::Incoming, header::USER_AGENT};
|
||||
use hyper_proxy2::{Intercept, Proxy, ProxyConnector};
|
||||
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
|
||||
use hyper_util::{
|
||||
client::legacy::{Client, ResponseFuture, connect::HttpConnector},
|
||||
rt::TokioExecutor,
|
||||
|
@ -23,6 +22,11 @@ use parking_lot::Mutex;
|
|||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))]
|
||||
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
|
||||
#[cfg(all(feature = "native-tls", not(feature = "rustls-tls")))]
|
||||
use hyper_tls::HttpsConnector;
|
||||
|
||||
use crate::{
|
||||
Error,
|
||||
config::{OS, os_version},
|
||||
|
@ -145,14 +149,15 @@ impl HttpClient {
|
|||
|
||||
fn try_create_hyper_client(proxy_url: Option<&Url>) -> Result<HyperClient, Error> {
|
||||
// configuring TLS is expensive and should be done once per process
|
||||
let _ = rustls::crypto::ring::default_provider()
|
||||
.install_default()
|
||||
.map_err(|e| {
|
||||
Error::internal(format!("unable to install default crypto provider: {e:?}"))
|
||||
});
|
||||
|
||||
let tls = HttpsConnectorBuilder::new().with_webpki_roots();
|
||||
let https_connector = tls.https_or_http().enable_http1().enable_http2().build();
|
||||
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))]
|
||||
let https_connector = {
|
||||
let tls = HttpsConnectorBuilder::new().with_platform_verifier();
|
||||
tls.https_or_http().enable_http1().enable_http2().build()
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "native-tls", not(feature = "rustls-tls")))]
|
||||
let https_connector = HttpsConnector::new();
|
||||
|
||||
// When not using a proxy a dummy proxy is configured that will not intercept any traffic.
|
||||
// This prevents needing to carry the Client Connector generics through the whole project
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue