0.5.1: axum-only apub_federation, rustls ring-only, install ring provider
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## [0.5.1] — 2026-10-26
|
||||
|
||||
- build: axum-only activitypub_federation, rustls-ring only — drops actix-web and aws-lc from consumers' builds
|
||||
|
||||
## [0.5.0] — 2026-07-25
|
||||
|
||||
### Breaking changes
|
||||
|
||||
669
Cargo.lock
generated
669
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "k-ap"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
edition = "2024"
|
||||
description = "Generic ActivityPub protocol layer"
|
||||
license = "MIT"
|
||||
@@ -18,9 +18,10 @@ thiserror = "2"
|
||||
tracing = "0.1"
|
||||
async-trait = "0.1"
|
||||
axum = { version = "0.8", features = ["macros"] }
|
||||
reqwest = { version = "0.13", features = ["json"] }
|
||||
reqwest = { version = "0.13", default-features = false, features = ["json", "charset", "http2", "system-proxy", "rustls-no-provider"] }
|
||||
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
|
||||
url = { version = "2", features = ["serde"] }
|
||||
enum_delegate = "0.2"
|
||||
activitypub_federation = "0.7.0-beta.11"
|
||||
activitypub_federation = { version = "0.7.0-beta.11", default-features = false, features = ["axum"] }
|
||||
zeroize = { version = "1", features = ["derive"] }
|
||||
paste = "1"
|
||||
|
||||
@@ -37,6 +37,7 @@ impl ApFederationConfig {
|
||||
debug: bool,
|
||||
signing_actor: Option<&DbActor>,
|
||||
) -> anyhow::Result<Self> {
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let config = if debug {
|
||||
FederationConfig::builder()
|
||||
.domain(&data.domain)
|
||||
|
||||
@@ -11,6 +11,7 @@ pub mod service;
|
||||
/// Mock builders for testing. Not behind `#[cfg(test)]` so downstream crates
|
||||
/// can use them in their own test suites.
|
||||
pub mod testing;
|
||||
pub(crate) mod tls;
|
||||
pub(crate) mod url_scheme;
|
||||
pub(crate) mod urls;
|
||||
pub(crate) mod user;
|
||||
|
||||
@@ -21,6 +21,7 @@ impl ActivityPubService {
|
||||
) -> anyhow::Result<()> {
|
||||
let outbox_parsed = url::Url::parse(outbox_url)?;
|
||||
crate::security::validate_url(&outbox_parsed).await?;
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(
|
||||
super::HTTP_FETCH_TIMEOUT_SECS,
|
||||
|
||||
@@ -30,6 +30,7 @@ fn webfinger_url(handle: &ParsedHandle<'_>) -> String {
|
||||
async fn fetch_webfinger(url: &str) -> anyhow::Result<serde_json::Value> {
|
||||
let parsed = Url::parse(url)?;
|
||||
crate::security::validate_url(&parsed).await?;
|
||||
crate::tls::ensure_crypto_provider();
|
||||
Ok(reqwest::Client::new()
|
||||
.get(url)
|
||||
.header("Accept", "application/jrd+json, application/json")
|
||||
|
||||
@@ -279,6 +279,7 @@ async fn setup_with_blocklist(
|
||||
Arc::new(crate::url_scheme::DefaultUrlScheme),
|
||||
);
|
||||
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let config = FederationConfig::builder()
|
||||
.domain(LOCAL_DOMAIN)
|
||||
.app_data(data)
|
||||
|
||||
@@ -103,6 +103,7 @@ async fn check_guards_idempotency() {
|
||||
build_user_repo(uuid::Uuid::new_v4(), "alice"),
|
||||
MockObjectHandlerBuilder::new().build(),
|
||||
);
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let config = FederationConfig::builder()
|
||||
.domain("example.com")
|
||||
.app_data(data_inner)
|
||||
@@ -139,6 +140,7 @@ async fn check_guards_blocks_domain() {
|
||||
build_user_repo(uuid::Uuid::new_v4(), "alice"),
|
||||
MockObjectHandlerBuilder::new().build(),
|
||||
);
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let config = FederationConfig::builder()
|
||||
.domain("example.com")
|
||||
.app_data(data_inner)
|
||||
@@ -170,6 +172,7 @@ async fn extract_and_dispatch_mentions_notifies_local_users() {
|
||||
})
|
||||
.build();
|
||||
let data_inner = make_data(None, build_user_repo(local_user_id, "alice"), handler);
|
||||
crate::tls::ensure_crypto_provider();
|
||||
let config = FederationConfig::builder()
|
||||
.domain("example.com")
|
||||
.app_data(data_inner)
|
||||
|
||||
30
src/tls.rs
Normal file
30
src/tls.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
//! rustls crypto provider setup.
|
||||
//!
|
||||
//! k-ap compiles rustls with the `ring` provider only (no aws-lc). reqwest 0.13
|
||||
//! does not auto-select a provider in that configuration and panics
|
||||
//! ("No provider set") on client construction, so we install ring as the
|
||||
//! process default before any HTTP client is built. Idempotent; a provider
|
||||
//! already installed by the host application wins.
|
||||
|
||||
pub(crate) fn ensure_crypto_provider() {
|
||||
static ONCE: std::sync::Once = std::sync::Once::new();
|
||||
ONCE.call_once(|| {
|
||||
// Err means the application already installed a provider; keep theirs.
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn installs_provider_and_client_builds() {
|
||||
ensure_crypto_provider();
|
||||
ensure_crypto_provider();
|
||||
assert!(rustls::crypto::CryptoProvider::get_default().is_some());
|
||||
reqwest::Client::builder()
|
||||
.build()
|
||||
.expect("reqwest client builds with ring-only rustls");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user