Merge pull request #663 from fengalin/fix/external/qbzd-add-tls-provider

fix(qbzd): add tls provider
This commit is contained in:
Victor RH authored and GitHub committed 2026-07-26 16:42:35 -06:00
commit fe2be63f0f
11 files changed
+28 -116

No files matched your search

+1 -69
View File
@@ -2615,10 +2615,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
@@ -2628,11 +2626,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi 5.3.0",
"wasip2",
"wasm-bindgen",
]
[[package]]
@@ -4212,12 +4208,6 @@ dependencies = [
"hashbrown 0.17.1",
]
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "lyon_algorithms"
version = "1.0.20"
@@ -5943,6 +5933,7 @@ dependencies = [
"rand 0.10.1",
"reqwest",
"rusqlite",
"rustls",
"serde",
"serde_json",
"tokio",
@@ -5998,7 +5989,6 @@ dependencies = [
"mdns-sd",
"rupnp",
"rust_cast",
"rustls",
"serde",
"serde_json",
"thiserror 2.0.18",
@@ -6526,61 +6516,6 @@ dependencies = [
"serde",
]
[[package]]
name = "quinn"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
"socket2 0.6.3",
"thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"bytes",
"getrandom 0.3.4",
"lru-slab",
"rand 0.9.3",
"ring",
"rustc-hash 2.1.1",
"rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
name = "quinn-udp"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.6.3",
"tracing",
"windows-sys 0.60.2",
]
[[package]]
name = "quote"
version = "1.0.45"
@@ -7001,7 +6936,6 @@ dependencies = [
"log",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pki-types",
"serde",
@@ -7280,7 +7214,6 @@ dependencies = [
"aws-lc-rs",
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
@@ -7305,7 +7238,6 @@ version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
]
+1 -1
View File
@@ -59,7 +59,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
# HTTP
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls", "cookies", "stream"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls-webpki-roots-no-provider", "cookies", "stream"] }
# Logging
log = "0.4"
+3
View File
@@ -24,3 +24,6 @@ chrono = { workspace = true }
md-5 = { workspace = true }
base64 = { workspace = true }
rand = "0.10"
# TLS provider selection
rustls = { version = "0.23", features = ["aws_lc_rs"] }
+17
View File
@@ -10,3 +10,20 @@ pub mod session_store;
pub mod shell;
pub mod settings;
pub mod user_data;
/// Install the rustls process-level `CryptoProvider` (aws-lc-rs) exactly once.
///
/// Idempotent (a second call is a no-op); harmless if some other component
/// already installed a default (`install_default` then returns Err, ignored).
pub fn ensure_crypto_provider() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| {
if rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.is_err()
{
log::debug!("[app] rustls CryptoProvider already installed");
}
});
}
-6
View File
@@ -8,12 +8,6 @@ description = "Casting support for QBZ - Chromecast, DLNA"
# Chromecast
rust_cast = "0.21"
# TLS provider selection. rust_cast uses rustls; in the multi-crate binary both
# the aws-lc-rs and ring providers end up enabled (reqwest pulls ring), so
# rustls can't auto-pick one and panics on connect. We install aws-lc-rs
# explicitly before connecting (see `ensure_crypto_provider`).
rustls = { version = "0.23", features = ["aws_lc_rs"] }
# mDNS discovery
mdns-sd = "0.11"
-3
View File
@@ -75,9 +75,6 @@ impl ChromecastHandle {
/// Connect to a Chromecast device
pub fn connect(&self, ip: String, port: u16) -> Result<(), CastError> {
// rust_cast opens a rustls TLS channel; make sure a CryptoProvider is
// installed first (the worker thread would otherwise panic).
crate::ensure_crypto_provider();
let (reply_tx, reply_rx) = mpsc::channel();
self.sender
.send(CastCommand::Connect {
-3
View File
@@ -60,9 +60,6 @@ pub struct DlnaConnection {
impl DlnaConnection {
/// Connect to a DLNA device and discover service URLs
pub async fn connect(device: DiscoveredDlnaDevice) -> Result<Self, DlnaError> {
// Defensive: the device-description fetch may go over TLS in some
// setups; ensure a rustls CryptoProvider is installed (idempotent).
crate::ensure_crypto_provider();
let device_url: Uri = device
.url
.parse()
-22
View File
@@ -38,25 +38,3 @@ pub use dlna::{
/// Cast device type alias for backwards compatibility
pub type CastDevice = CastDeviceConnection;
/// Install the rustls process-level `CryptoProvider` (aws-lc-rs) exactly once.
///
/// `rust_cast` opens a TLS control channel to the Chromecast via rustls. In the
/// full QBZ binary BOTH the `aws-lc-rs` and `ring` providers are enabled (reqwest
/// pulls `ring`, rust_cast pulls `aws-lc-rs`), so rustls can't auto-select one
/// and panics with "Could not automatically determine the process-level
/// CryptoProvider". Installing one explicitly before any TLS use fixes it.
///
/// Idempotent (a second call is a no-op); harmless if some other component
/// already installed a default (`install_default` then returns Err, ignored).
pub fn ensure_crypto_provider() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| {
if rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.is_err()
{
log::debug!("[cast] rustls CryptoProvider already installed");
}
});
}
+1 -1
View File
@@ -10,7 +10,7 @@ license = "MIT"
tokio = { version = "1", features = ["sync", "time"] }
# HTTP client
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
reqwest = { workspace = true, default-features = false, features = ["json", "rustls-tls-webpki-roots-no-provider"] }
# Serialization
serde = { version = "1", features = ["derive"] }
+2 -11
View File
@@ -8120,17 +8120,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Large/XL (and shrink RAM at Small). Set before any artwork job runs.
crate::artwork::set_ui_scale_factor(ui_scale_factor);
// Install the rustls process-level CryptoProvider ONCE, before ANY TLS use.
// The full binary compiles BOTH rustls providers (aws-lc-rs via qbz-cast's
// rust_cast, ring via reqwest), so rustls cannot auto-select one and panics
// ("Could not automatically determine the process-level CryptoProvider") the
// first time a TLS connection opens. Previously this was only installed lazily
// on the cast paths, so QConnect's tokio-tungstenite WebSocket (it opens a
// rustls TLS channel on its own worker thread) panicked when the user joined a
// session WITHOUT ever casting. Installing here at startup covers every TLS
// consumer — QConnect, cast, reqwest — regardless of which connects first.
// Idempotent (the cast paths still call it; the second call is a no-op).
qbz_cast::ensure_crypto_provider();
// Install the rustls process-level `CryptoProvider`
qbz_app::ensure_crypto_provider();
let tokio_rt = tokio::runtime::Runtime::new()?;
let _enter = tokio_rt.enter();
+3
View File
@@ -256,6 +256,9 @@ enum ConfigCmd { Path, Show { #[arg(long)] json: bool } }
#[tokio::main]
async fn main() {
// Install the rustls process-level `CryptoProvider`
qbz_app::ensure_crypto_provider();
let cli = Cli::parse();
let code = match cli.cmd {
Cmd::Version { json } => {