From c36b45d11fff8549a9bbc90aeeb4026232811066 Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Sun, 30 Mar 2025 15:58:04 +0100 Subject: [PATCH 1/7] add proper linker for musl --- .cargo/config.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..33654dd --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[target.x86_64-unknown-linux-musl] +linker = "x86_64-linux-musl-gcc" + From e1ed4f885ec018366ae408e58dbf6c1f12eab3fb Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Sun, 30 Mar 2025 17:31:59 +0100 Subject: [PATCH 2/7] Match updated requirements for workload identity --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 94 +++++++++++- src/child.rs | 4 +- src/env.rs | 342 -------------------------------------------- src/identity/mod.rs | 82 ++++++++++- src/lib.rs | 1 - src/main.rs | 89 +++++++++--- src/proxy.rs | 135 ++++++++++++++++- 9 files changed, 368 insertions(+), 383 deletions(-) delete mode 100644 src/env.rs diff --git a/Cargo.lock b/Cargo.lock index 6f3989c..fdbb0bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -829,7 +829,7 @@ dependencies = [ [[package]] name = "factor" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 9056794..759c43f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factor" -version = "0.1.0" +version = "0.2.0" description = "Run twelve-factor apps locally" repository = "https://github.com/twelve-factor/factor" keywords = ["container", "kubernetes", "platform", "twelve-factor"] diff --git a/README.md b/README.md index a0049c2..e9f3ca6 100644 --- a/README.md +++ b/README.md @@ -106,14 +106,53 @@ In another terminal window, load the file and make a request passing in the token: ```shell -$ TOKEN=$(cat DEFAULT.token) \ +$ TOKEN=$(cat DEFAULT.token); \ curl -v -H "Authorization: Bearer $TOKEN" http://localhost:5000 ``` -You should see `X-Factor-Client-Id: DEFAULT` in the response from the server. +You should see `X-Client-Id: DEFAULT` in the response from the server. Note that in this case we are generating an oidc token and validating it locally. +## Architecture and Configuration + +Factor CLI acts as a platform that provides services to your application in the same way a cloud platform would. This platform is configured through environment variables and provides services through environment variables and headers. + +### Client-Side Identity + +On the client side, Factor acts as an identity provider that generates tokens for your application to use when calling other services: + +**Configuration (what your application provides to Factor):** + +- `*_AUDIENCE` environment variables - Define the audiences for which Factor should generate tokens + - Example: `DEFAULT_AUDIENCE=api.example.com` will generate a token for the audience "api.example.com" + +**Services (what Factor provides to your application):** + +- `*_CREDS` environment variables - Contain credentials that your application can use to authenticate to other services + - Example: `DEFAULT_CREDS='{"type":"oidc","data":{"token":"file:///path/to/DEFAULT.token"}}'` +- Token files - Written to disk and referenced by the `*_CREDS` variables + - These files are automatically updated by Factor (typically every 15 minutes) + - Applications should monitor and reload these files when they change to maintain valid credentials + +### Server-Side Identity + +On the server side, Factor acts as an identity-aware proxy that validates incoming tokens and passes identity information to your application: + +**Configuration (what your application provides to Factor):** + +- `*_CLIENT_CREDS` environment variables - Define the client identities that are allowed to access your application + - Example: `SERVICE_A_CLIENT_CREDS='{"type":"oidc","data":{"iss":"https://auth\\.example\\.com","sub":"service-.*","aud":"api"}}'` +- `REJECT_UNKNOWN` environment variable - When set to "true", rejects requests from unidentified clients + - When not set or "false", requests without valid tokens will pass through without the `X-Client-Id` header + +**Services (what Factor provides to your application):** + +- `X-Client-Id` header - Contains the client ID of the authenticated caller, validated from their token + - Example: When a request comes in with a valid token, your application receives `X-Client-Id: SERVICE_A` + +This separation of concerns allows your application to focus on its business logic while Factor handles the complexities of identity management, token validation, and proxy configuration. + ## Governance and Code of Conduct This project follows the main [twelve-factor @@ -135,7 +174,25 @@ Loads an `.env` file if available, starts the given subcommand and proxies requests to the subcommand. Validates incoming bearer tokens using the same mechanism as `proxy` and syncs ids using the same mechanism as `id`. Audiences can also be specified by setting `CLIENT_ID_AUDIENCE=` in environment -variables. +variables. Token files will be created in the current working directory. + +The application will receive credentials through environment variables using the `*_CREDS` suffix format: + +```json +{ + "type": "oidc", + "data": { + "token": "file:///path/to/token/file" + } +} +``` + +For example: + +```shell +# The environment variable name before _CREDS becomes the credential name +export SERVICE_CREDS='{"type":"oidc","data":{"token":"file:///tmp/service.token"}}' +``` Additionally, if an ngrok key is specified in the app config, it will start an ngrok tunnel and forward requests to the application. The ngrok url is @@ -152,9 +209,11 @@ by specifying `--path` on the command line or changing the path value in Listens on `--port` and proxies requests to `--child_port`. Validates incoming bearer tokens based on the flag `--incoming-identity` or `INCOMING_IDENTITY` in -the environment. Identity data looks like: +the environment. Identity data can be provided in two ways: -``` +1. As a JSON/TOML file specified by `--incoming-identity`: + +```json { "": { "iss": "", @@ -168,8 +227,29 @@ the environment. Identity data looks like: } ``` -If a matching token is supplied, then the header `X-Factor-Client-Id` will be -set to the value of the matching client id. To reject, requests that don't +2. Through environment variables using the `*_CLIENT_CREDS` format: + +```json +{ + "type": "oidc", + "client_id": "optional_override", + "data": { + "iss": "", + "sub": "", + "aud": "" + } +} +``` + +For example: + +```shell +# The client_id field is optional - if omitted, the environment variable name without _CLIENT_CREDS is used +export SERVICE_A_CLIENT_CREDS='{"type":"oidc","data":{"iss":"https://auth\\.example\\.com","sub":"service-.*","aud":"api"}}' +``` + +If a matching token is supplied, then the header `X-Client-Id` will be +set to the value of the matching client id. To reject requests that don't match, use the flag `--reject-unknown` `factor info` diff --git a/src/child.rs b/src/child.rs index c25b1af..b5f508e 100644 --- a/src/child.rs +++ b/src/child.rs @@ -1,3 +1,5 @@ +use std::env; + use async_trait::async_trait; use log::{error, trace, warn}; use tokio::{ @@ -6,7 +8,7 @@ use tokio::{ time::{sleep, Duration}, }; -use super::{env, server::Service}; +use super::server::Service; pub struct ChildService { command: Vec, diff --git a/src/env.rs b/src/env.rs deleted file mode 100644 index 1ca92fd..0000000 --- a/src/env.rs +++ /dev/null @@ -1,342 +0,0 @@ -use std::{ - borrow::Cow, - env, - env::VarError, - ffi::OsStr, - fs, - path::{Path, PathBuf}, - sync::Arc, -}; - -use anyhow::Result; -use log::error; -use notify::{Event, RecursiveMode, Watcher}; -use reqwest; -use serde::de::DeserializeOwned; -use shellexpand::LookupError; - -// Callbacks can be either string or typed -pub type StringCallback = Arc; -pub type TypedCallback = Arc; - -/// Gets an environment variable with support for reference resolution and type conversion. -/// If `__REF__VAR_NAME` exists, it will load the value from the URI specified in that variable. -/// Supports file:// and http(s):// URIs. -/// -/// # Errors -/// -/// Returns `VarError::NotPresent` if: -/// - The environment variable (`__REF__{key}`) doesn't exist -/// -/// Returns `VarError::InvalidReference` if: -/// - The environment variable is a reference (`__REF__` prefix) but: -/// - The URI is invalid -/// - HTTP request fails -/// - File read fails -/// - File read fails -pub fn var_json_with_on_change, T>( - key: K, - on_change: Option>, -) -> Result -where - T: DeserializeOwned + Send + Sync + 'static, -{ - let string_callback = on_change.map(|cb| { - let cb_clone = cb.clone(); - Arc::new(move |s: String| { - if let Ok(val) = serde_json::from_str(&s) { - cb_clone(val); - } - }) as StringCallback - }); - - let string_value = var_with_on_change(key, string_callback)?; - - let value = serde_json::from_str(&string_value).map_err(|e| { - error!("Failed to parse JSON: {}", e); - VarError::NotPresent - })?; - Ok(value) -} - -/// # Errors -/// -/// Returns `VarError::NotPresent` if: -/// -/// - The environment variable (`__REF__{key}`) doesn't exist -/// - The contents of the environment variable can't be parsed as JSON -/// - The value of the environment variable can't be converted to the desired -/// type (`T`) -pub fn var_json, T>(key: K) -> Result -where - T: DeserializeOwned + Send + Sync + 'static, -{ - let string_value = var(key)?; - let value = serde_json::from_str(&string_value).map_err(|e| { - error!("Failed to parse JSON: {}", e); - VarError::NotPresent - })?; - Ok(value) -} - -/// # Errors -/// -/// Returns `VarError::NotPresent` if: -/// -/// - The environment variable (`__REF__{key}`) doesn't exist -pub fn var_with_on_change>( - key: K, - on_change: Option, -) -> Result { - if let Some(key_str) = key.as_ref().to_str() { - let ref_key = format!("__REF__{key_str}"); - if let Ok(ref_value) = env::var(&ref_key) { - return resolve_reference(&ref_value, on_change); - } - } - env::var(key) -} - -/// # Errors -/// -/// Returns `VarError::NotPresent` if: -/// -/// - The environment variable (`__REF__{key}`) doesn't exist -pub fn var>(key: K) -> Result { - var_with_on_change(key.as_ref(), None) -} - -// TODO: support a non-blocking version of this -/// # Errors -/// -/// Returns `VarError::NotPresent` if: -/// -/// - For `file://` URIs: -/// - File doesn't exist -/// - See [`std::fs::OpenOptions::open`] -/// - For `http(s)://` URIs: -/// - Network request fails. See [`reqwest::blocking::get`] -/// - The network response had a `charset` parameter, but the content can't be -/// decoded with that encoding. -/// - The network response doesn't have a `charset` parameter, and the content -/// can't be decoded with UTF-8 -/// -/// Other schemes are not supported, and will return `VarError::NotPresent`. -// TODO: These should probably return `VarError::InvalidReference` instead -fn resolve_reference(uri: &str, on_change: Option) -> Result { - if uri.starts_with("file://") { - let path = uri.trim_start_matches("file://"); - let content = fs::read_to_string(path).map_err(|_| VarError::NotPresent)?; - - // If callback provided, set up file watching - if let Some(callback) = on_change { - watch_file(&path, callback).map_err(|_| VarError::NotPresent)?; - } - - Ok(content.trim().to_string()) - } else if uri.starts_with("http://") || uri.starts_with("https://") { - let content = reqwest::blocking::get(uri) - .map_err(|_| VarError::NotPresent)? - .text() - .map_err(|_| VarError::NotPresent)?; - Ok(content.trim().to_string()) - } else { - Err(VarError::NotPresent) - } -} - -fn watch_file(path: &impl AsRef, callback: StringCallback) -> Result<()> { - // Copy the path to an owned PathBuf so it can be shared with the watcher - let path_buf = path.as_ref().to_path_buf(); - - let mut watcher = notify::recommended_watcher(move |res: Result| { - if let Ok(event) = res { - if event.kind.is_modify() { - if let Ok(content) = std::fs::read_to_string(&path_buf) { - callback(content.trim().to_string()); - } - } - } - })?; - - watcher.watch(path.as_ref(), RecursiveMode::NonRecursive)?; - - // Store watcher to keep it alive - std::mem::forget(watcher); // Prevent watcher from being dropped - Ok(()) // Return Ok result -} - -pub fn set_var, V: AsRef>(key: K, value: V) { - env::set_var(key.as_ref(), value.as_ref()); -} - -#[must_use] -pub fn vars() -> env::Vars { - env::vars() -} - -/// # Errors -/// -/// Returns `anyhow::Error` in these common error conditions caused by the user: -/// -/// - `path` is the root (and therefore has no parent) -/// - The parent of the path doesn't exist -/// -/// See [`set_var_file_with_remap`] for more error conditions -/// -/// TODO: separate user errors (which should be reported as-is to the user) from -/// permission errors. -pub fn set_var_file( - key: impl AsRef, - value: impl AsRef, - path: &PathBuf, -) -> Result<()> { - set_var_file_with_remap(key, value, path, None, None) -} - -/// # Errors -/// -/// Returns `anyhow::Error` in these common error conditions caused by the user: -/// -/// - `path` is the root (and therefore has no parent) -/// - The parent of the path doesn't exist -/// -/// Permission issues: -/// -/// - A temporary file can't be created -/// - A successfully created temporary file can't be written to -/// - A successfully created temporary file can't be renamed to the specified path -/// -/// More rarely: -/// -/// - The key is not valid UTF-8 -/// - The path is not valid UTF-8 -pub fn set_var_file_with_remap( - key: impl AsRef, - value: impl AsRef, - path: &PathBuf, - from: Option<&str>, - to: Option<&str>, -) -> Result<()> { - let canonicalized_parent = path - .parent() - .ok_or(VarError::NotPresent)? - .canonicalize() - .map_err(|e| { - anyhow::anyhow!("Failed to get canonical parent path from {:?}: {}", path, e) - })?; - let file_name = path - .file_name() - .ok_or(VarError::NotPresent)? - .to_str() - .ok_or(VarError::NotPresent)?; - let canonical_path = canonicalized_parent.join(file_name); // Create PathBuf here - let path_str = canonical_path.to_str().ok_or(VarError::NotPresent)?; // path_str is now derived from rename_path - - let remapped_path = match (from, to) { - (Some(from_str), Some(to_str)) => path_str.replace(from_str, to_str), - _ => path_str.to_string(), - }; - let ref_key = format!( - "__REF__{}", - key.as_ref().to_str().ok_or(VarError::NotPresent)? - ); - set_var(ref_key, format!("file://{}", &remapped_path)); - let temp_file = tempfile::NamedTempFile::new() - .map_err(|e| anyhow::anyhow!("Failed to create temporary file: {}", e))?; - let temp_path = temp_file.into_temp_path(); - fs::write(&temp_path, value.as_ref().to_string_lossy().as_bytes()) - .map_err(|e| anyhow::anyhow!("Failed to write to temporary file: {}", e))?; - fs::rename(&temp_path, &canonical_path) - .map_err(|e| anyhow::anyhow!("Failed to rename temporary file: {}", e))?; - Ok(()) -} - -/// # Errors -/// -/// Returns `anyhow::Error` if the value can't be serialized to JSON -pub fn set_var_json(key: impl AsRef, value: &impl serde::Serialize) -> Result<()> { - let json_string = serde_json::to_string(value)?; - set_var(key, &json_string); - Ok(()) -} - -/// # Errors -/// -/// See [`set_var_json_file_with_remap`] -pub fn set_var_json_file, V>(key: K, value: &V, path: &PathBuf) -> Result<()> -where - V: serde::Serialize, -{ - set_var_json_file_with_remap(key, value, path, None, None) -} - -/// # Errors -/// -/// Returns `anyhow::Error` if: -/// -/// - the value can't be serialized to JSON -/// - the specified path is the root (and therefore has no parent) -/// - the parent of the path doesn't exist -/// -/// See [`set_var_file_with_remap`] for more uncommon error conditions -pub fn set_var_json_file_with_remap, V>( - key: K, - value: &V, - path: &PathBuf, - from: Option<&str>, - to: Option<&str>, -) -> Result<()> -where - V: serde::Serialize, -{ - let json_string = serde_json::to_string(value)?; - set_var_file_with_remap(key, json_string.as_str(), path, from, to) -} - -/// # Errors -/// -/// Returns `anyhow::Error` if: -/// -/// - The environment variable (`__REF__{key}`) doesn't exist -/// - The input string has invalid syntax (e.g., unclosed `${` braces) -pub fn expand(input: &str) -> Result { - Ok(shellexpand::env_with_context( - input, - |key| -> Result, LookupError> { - var(key) - .map(Some) - .map_err(|e| LookupError { - var_name: key.to_string(), - cause: e, - }) - .or(Ok::, LookupError>(None)) - }, - ) - .map(Cow::into_owned)?) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_expand_with_file() { - let key = "TEST_EXPAND_VAR"; - let value = "TestValue"; - let temp_file = tempfile::NamedTempFile::new().unwrap(); - let temp_path = temp_file.into_temp_path(); - assert!(set_var_file(key, value, &temp_path.to_path_buf()).is_ok()); - assert_eq!(var(key).unwrap(), value); - - let input = format!("Prefix-${key}-Suffix"); - - let expected = format!("Prefix-{value}-Suffix"); - - let result = expand(&input).unwrap(); - - assert_eq!(result, expected); - - env::remove_var(key); - } -} diff --git a/src/identity/mod.rs b/src/identity/mod.rs index 13747e5..0342b2d 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -11,7 +11,7 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use tokio::{sync::watch, time::interval}; -use super::{dirs, env, server::Service}; +use super::{dirs, server::Service}; macro_rules! identity_providers { ($($variant:ident),*) => { @@ -69,6 +69,70 @@ pub trait IdentityProvider: Send + Sync { } } +#[derive(Debug, Serialize)] +struct TokenCredentials { + #[serde(rename = "type")] + cred_type: String, + data: TokenData, +} + +#[derive(Debug, Serialize)] +struct TokenData { + token: String, +} + +impl TokenCredentials { + fn new(token_path: impl AsRef) -> Self { + Self { + cred_type: "oidc".to_string(), + data: TokenData { + token: format!("file://{}", token_path.as_ref().display()), + }, + } + } +} + +/// Write a value to a file idempotently using a temporary file +/// +/// # Errors +/// +/// Returns an error if: +/// - The parent directory doesn't exist +/// - Cannot create a temporary file +/// - Cannot write to the temporary file +/// - Cannot rename the temporary file +fn write_file_idempotent(path: impl AsRef, contents: &str) -> Result<()> { + let path = path.as_ref(); + + // Ensure parent directory exists and get canonical path + let canonicalized_parent = path + .parent() + .ok_or_else(|| anyhow!("Path has no parent directory"))? + .canonicalize() + .map_err(|e| anyhow!("Failed to get canonical parent path: {}", e))?; + + let file_name = path + .file_name() + .ok_or_else(|| anyhow!("Path has no filename"))?; + + let canonical_path = canonicalized_parent.join(file_name); + + // Create temporary file in same directory + let temp_file = tempfile::NamedTempFile::new_in(&canonicalized_parent) + .map_err(|e| anyhow!("Failed to create temporary file: {}", e))?; + + // Write contents to temporary file + std::fs::write(temp_file.path(), contents) + .map_err(|e| anyhow!("Failed to write to temporary file: {}", e))?; + + // Atomically rename temporary file to target + temp_file + .persist(&canonical_path) + .map_err(|e| anyhow!("Failed to rename temporary file: {}", e))?; + + Ok(()) +} + pub struct IdentitySyncService { pub key: String, path: PathBuf, @@ -82,8 +146,7 @@ impl IdentitySyncService { /// - Returns [`anyhow::Error`] if: /// - `path` is the root or parent directory doesn't exist /// - permission issues - /// - /// See [`env::set_var_file`] for more error conditions + /// - cannot create or write to temporary files pub fn new( path: &str, target_id: &str, @@ -95,12 +158,17 @@ impl IdentitySyncService { .replace_all(target_id, "_") .to_string() .to_uppercase(); - let key = format!("{}_{}", target_id_safe, "IDENTITY"); + let key = format!("{}_{}", target_id_safe, "CREDS"); let filename = format!("{target_id}.token"); let path = PathBuf::from(path).join(filename); - // make sure that we empty any existing old identity - env::set_var_file(&key, "", &path)?; + // Write initial empty token file + write_file_idempotent(&path, "")?; + + // Set credentials environment variable + let creds = TokenCredentials::new(&path); + std::env::set_var(&key, serde_json::to_string(&creds)?); + let service = IdentitySyncService { key: key.clone(), path, @@ -144,7 +212,7 @@ impl Service for IdentitySyncService { _ = period.tick() => { match self.provider.get_token(&self.audience).await { Ok(token) => { - match env::set_var_file(&self.key, &token, &self.path) { + match write_file_idempotent(&self.path, &token) { Ok(()) => { trace!("Successfully wrote token for audience {} to file", self.audience); match get_claims(&token) { diff --git a/src/lib.rs b/src/lib.rs index 1f4a58d..1826613 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ pub mod child; pub mod dirs; -pub mod env; pub mod identity; pub mod ngrok; pub mod proxy; diff --git a/src/main.rs b/src/main.rs index 2428d70..3e320d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,52 @@ use std::{ - collections::HashMap, io::Write, net::TcpListener, path::Path, sync::Arc, time::Duration, + borrow::Cow, collections::HashMap, env, io::Write, net::TcpListener, path::Path, sync::Arc, + time::Duration, }; +use anyhow::Result; use clap::{Parser, Subcommand}; use dotenvy::dotenv; use factor::{ - child, dirs, env, identity, identity::IdProvider, ngrok, proxy, proxy::IncomingIdentity, + child, dirs, + identity::{self, IdProvider}, + ngrok, proxy, }; use log::{debug, info, trace, warn}; use notify::{Event, RecursiveMode, Watcher}; use serde::{Deserialize, Serialize}; +use shellexpand::LookupError; use tokio::{ + self, runtime::Runtime, signal, sync::{oneshot, watch}, time::sleep, }; +/// Expand environment variables in a string using the ${VAR} syntax +/// +/// # Errors +/// +/// Returns `anyhow::Error` if: +/// +/// - The environment variable (`${key}`) doesn't exist +/// - The input string has invalid syntax (e.g., unclosed `${` braces) +pub fn expand(input: &str) -> Result { + Ok(shellexpand::env_with_context( + input, + |key| -> Result, LookupError> { + env::var(key) + .map(Some) + .map_err(|e| LookupError { + var_name: key.to_string(), + cause: e, + }) + .or(Ok::, LookupError>(None)) + }, + ) + .map(Cow::into_owned)?) +} + #[derive(Debug, Default, Deserialize, Serialize)] struct GlobalConfig { id: Option, @@ -85,18 +115,18 @@ fn load_global_config() -> Result { fn load_app_config(path: &str) -> Result { match std::fs::read_to_string(path) { Ok(contents) => { - let expanded_contents = env::expand(&contents)?; + let expanded_contents = expand(&contents)?; Ok(toml::from_str(&expanded_contents)?) } Err(_) => Ok(AppConfig::default()), } } -fn load_incoming_identity(path: &str) -> Result { +fn load_incoming_identity(path: &str) -> Result { let contents = std::fs::read_to_string(path) .map_err(|e| anyhow::anyhow!("Failed to read incoming identity file at {}: {}", path, e))?; toml::from_str(&contents).or_else(|e| { - warn!("Failed to parse {path} as TOML, trying JSON: {e}"); + debug!("Failed to parse {path} as TOML, trying JSON: {e}"); serde_json::from_str(&contents) .map_err(|e| anyhow::anyhow!("Failed to parse {} as TOML or JSON: {}", path, e)) }) @@ -167,7 +197,7 @@ enum Commands { /// Proxy from `PORT` to `CHILD_PORT` Proxy { /// Reject requests from unknown clients - #[arg(long, default_value = "false")] + #[arg(long, env = "REJECT_UNKNOWN", default_value = "false", value_parser = clap::builder::BoolishValueParser::new())] reject_unknown: bool, /// Use IPv6 instead of IPv4 @@ -201,7 +231,7 @@ enum Commands { incoming_identity: Option, /// Listening port for proxy - #[arg(long, env = "PORT", value_parser = clap::value_parser!(u16), default_value = "5000")] + #[arg(long, value_parser = clap::value_parser!(u16), default_value = "5000")] port: u16, /// Command to execute @@ -742,7 +772,24 @@ fn add_services( ipv6: bool, command: &[String], ) -> Result<(), anyhow::Error> { + // Load .env file variables into the environment dotenv().ok(); + + // Check environment for overrides (this will include variables from .env) + let reject_unknown = match env::var("REJECT_UNKNOWN") { + Ok(val) => { + let val = val.to_lowercase(); + matches!(val.as_str(), "true" | "t" | "yes" | "y" | "1" | "on") + } + Err(_) => reject_unknown, // Fall back to command-line value + }; + + // Get PORT from environment if set + let port = match env::var("PORT") { + Ok(val) => val.parse::().unwrap_or(port), // Parse or fall back to command-line + Err(_) => port, // Use command-line value + }; + let incoming_identity = get_incoming_identity(incoming_identity)?; let id = app_config @@ -766,7 +813,7 @@ fn add_services( .unwrap() .port(); - debug!("Proxying port {port} to {child_port}"); + debug!("Proxying port {port} to {child_port} (reject_unknown: {reject_unknown})"); let proxy_service = proxy::get_proxy_service( port, child_port, @@ -798,21 +845,29 @@ fn add_services( fn get_incoming_identity( incoming_identity_path: Option<&String>, -) -> Result { +) -> Result { debug!("incoming identity path: {incoming_identity_path:?}"); - let incoming_identity = match incoming_identity_path { + + // First try loading from file if specified + let mut incoming_identity = match incoming_identity_path { Some(incoming_identity_path) => load_incoming_identity(incoming_identity_path)?, - None => IncomingIdentity::default(), + None => proxy::IncomingIdentity::default(), }; - let incoming_identity = if incoming_identity.is_empty() { - env::var_json("INCOMING_IDENTITY").unwrap_or_else(|e| { - warn!("No INCOMING_IDENTITY specified, using default. Error: {e:?}"); + + // If empty, check INCOMING_IDENTITY env var + if incoming_identity.is_empty() { + incoming_identity = proxy::credentials::var_json("INCOMING_IDENTITY").unwrap_or_else(|e| { + debug!("No INCOMING_IDENTITY specified, checking for *_CLIENT_CREDS. Error: {e:?}"); HashMap::default() - }) + }); } else { env::set_var("INCOMING_IDENTITY", toml::to_string(&incoming_identity)?); - incoming_identity - }; + } + + // Load additional credentials from environment variables + if incoming_identity.is_empty() { + incoming_identity = proxy::credentials::load_from_env(); + } Ok(incoming_identity) } diff --git a/src/proxy.rs b/src/proxy.rs index af25c5c..323d1d3 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -9,7 +9,7 @@ use biscuit::{jwk::JWKSet, Empty}; use jsonwebtoken::{decode, decode_header, Algorithm, DecodingKey, Validation}; use log::{info, trace, warn}; use pingora::{server::configuration::ServerConf, services::listening::Service}; -use pingora_core::{upstreams::peer::HttpPeer, Result}; +use pingora_core::{upstreams::peer::HttpPeer, Result as PingoraResult}; use pingora_http::{RequestHeader, ResponseHeader}; use pingora_proxy::{HttpProxy, ProxyHttp, Session}; use regex::Regex; @@ -19,7 +19,126 @@ use tokio::sync::Mutex; use super::identity; -#[derive(Debug, Deserialize, Serialize, Clone)] +pub mod credentials { + use std::{collections::HashMap, env}; + + use anyhow::Result; + use log::{debug, warn}; + use serde::Deserialize; + + use super::IdentityValidator; + + #[derive(Debug, Deserialize)] + pub struct ClientCredentials { + #[serde(rename = "type")] + cred_type: String, + #[serde(default)] + client_id: String, + #[serde(default)] + data: IdentityValidator, + } + + /// Get a JSON-encoded environment variable and deserialize it + /// + /// # Errors + /// + /// Returns an error if: + /// - The environment variable doesn't exist + /// - The contents can't be parsed as JSON + /// - The value can't be converted to type `T` + pub fn var_json(key: &str) -> Result { + let string_value = env::var(key)?; + serde_json::from_str(&string_value).map_err(|e| { + anyhow::anyhow!("Failed to parse JSON from environment variable {key}: {e}") + }) + } + + fn load_incoming_identity(path: &str) -> anyhow::Result> { + let contents = std::fs::read_to_string(path).map_err(|e| { + anyhow::anyhow!("Failed to read incoming identity file at `{path}`: {e}") + })?; + toml::from_str(&contents).or_else(|e| { + warn!("Failed to parse `{path}` as TOML, trying JSON: {e}"); + serde_json::from_str(&contents) + .map_err(|e| anyhow::anyhow!("Failed to parse `{path}` as TOML or JSON: {e}")) + }) + } + + /// Get the incoming identity configuration from various sources + /// + /// # Errors + /// + /// Returns an error if: + /// - The identity file cannot be read or parsed + /// - The `INCOMING_IDENTITY` environment variable contains invalid JSON + /// - The identity configuration cannot be serialized back to `TOML` + pub fn get_incoming_identity( + incoming_identity_path: Option<&String>, + ) -> anyhow::Result> { + debug!("incoming identity path: {incoming_identity_path:?}"); + + // Load from file if specified + let mut incoming_identity = match incoming_identity_path { + Some(incoming_identity_path) => load_incoming_identity(incoming_identity_path)?, + None => HashMap::default(), + }; + + // Load from INCOMING_IDENTITY env var and merge + if let Ok(env_identity) = + var_json::>("INCOMING_IDENTITY") + { + for (key, value) in env_identity { + incoming_identity.insert(key, value); + } + } + + // Store back the merged identity + if !incoming_identity.is_empty() { + env::set_var("INCOMING_IDENTITY", toml::to_string(&incoming_identity)?); + } + + // Load and merge additional credentials from environment variables + let env_creds = load_from_env(); + for (key, value) in env_creds { + incoming_identity.insert(key, value); + } + + Ok(incoming_identity) + } + + /// Load identity configuration from environment variables + /// + /// # Returns + /// + /// Returns a `HashMap` mapping client IDs to their identity validators + #[must_use] + pub fn load_from_env() -> HashMap { + let mut incoming_identity = HashMap::new(); + for (key, _) in env::vars() { + if key.ends_with("_CREDS") { + let name = key.trim_end_matches("_CREDS"); + if let Ok(creds) = var_json::(&key) { + let client_id = if creds.client_id.is_empty() { + name.to_string() + } else { + creds.client_id.clone() + }; + if creds.cred_type == "oidc" { + incoming_identity.insert(client_id, creds.data); + } + } + } + } + if !incoming_identity.is_empty() { + if let Ok(toml) = toml::to_string(&incoming_identity) { + env::set_var("INCOMING_IDENTITY", toml); + } + } + incoming_identity + } +} + +#[derive(Debug, Deserialize, Serialize, Clone, Default)] pub struct IdentityValidator { iss: Option, sub: Option, @@ -174,7 +293,11 @@ impl ProxyHttp for AuthProxy { type CTX = (); fn new_ctx(&self) -> Self::CTX {} - async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result { + async fn request_filter( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> PingoraResult { if session.req_header().uri.path().starts_with("/.well-known/") { if let Ok(Some(jwks)) = self.provider.get_jwks().await { if let Err(e) = self.handle_well_known(session, jwks).await { @@ -185,12 +308,12 @@ impl ProxyHttp for AuthProxy { return Ok(true); // Indicate that the request has been handled } } - session.req_header_mut().remove_header("X-Factor-Client-Id"); + session.req_header_mut().remove_header("X-Client-Id"); match self.validate_token(session.req_header()).await { Ok(Some(client_id)) => { session .req_header_mut() - .append_header("X-Factor-Client-Id", client_id)?; + .append_header("X-Client-Id", client_id)?; return Ok(false); } Ok(None) => { @@ -212,7 +335,7 @@ impl ProxyHttp for AuthProxy { &self, _session: &mut Session, _ctx: &mut Self::CTX, - ) -> Result> { + ) -> PingoraResult> { // TODO: wrap pingora_load_balancer so we can put in both ipv4 and ipv6 upstreams? let addr = if self.ipv6 { SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), self.port) From d6ae80d272f1681bf5fe9e729b7f084c7760b819 Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Sun, 30 Mar 2025 18:25:50 +0100 Subject: [PATCH 3/7] override sfv version --- Cargo.lock | 1023 +++++++++++++++++++++++++++++++--------------------- Cargo.toml | 4 + 2 files changed, 607 insertions(+), 420 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdbb0bd..59acad2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,10 +24,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -56,9 +56,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -116,19 +116,20 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arc-swap" @@ -144,9 +145,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -184,18 +185,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -210,7 +211,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] @@ -239,9 +240,9 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "getrandom", + "getrandom 0.2.15", "instant", - "rand", + "rand 0.8.5", ] [[package]] @@ -279,9 +280,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "biscuit" @@ -294,7 +295,7 @@ dependencies = [ "num-bigint", "num-traits", "once_cell", - "ring 0.17.8", + "ring 0.17.14", "serde", "serde_json", ] @@ -307,9 +308,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "blake2" @@ -352,9 +353,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byteorder" @@ -364,15 +365,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.1" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -393,9 +394,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -403,7 +404,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -425,19 +426,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" dependencies = [ "clap_builder", - "clap_derive 4.5.18", + "clap_derive 4.5.32", ] [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" dependencies = [ "anstream", "anstyle", @@ -460,14 +461,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -487,9 +488,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.52" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] @@ -543,9 +544,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -561,27 +562,27 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" @@ -604,9 +605,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -614,34 +615,34 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "der" @@ -656,9 +657,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", "serde", @@ -714,7 +715,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -725,9 +726,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" [[package]] name = "educe" @@ -738,14 +739,14 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "enum-ordinalize" @@ -764,7 +765,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -779,38 +780,38 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -819,9 +820,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -836,7 +837,7 @@ dependencies = [ "base64 0.22.1", "biscuit", "chrono", - "clap 4.5.23", + "clap 4.5.34", "directories", "dirs", "dotenvy", @@ -855,7 +856,7 @@ dependencies = [ "pingora-core", "pingora-http", "pingora-proxy", - "rand", + "rand 0.8.5", "regex", "reqwest", "rsa", @@ -873,9 +874,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "filetime" @@ -891,9 +892,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "libz-ng-sys", @@ -908,9 +909,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -1001,7 +1002,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -1062,7 +1063,21 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", "wasm-bindgen", ] @@ -1074,9 +1089,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" dependencies = [ "atomic-waker", "bytes", @@ -1084,7 +1099,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.6.0", + "indexmap 2.8.0", "slab", "tokio", "tokio-util", @@ -1153,12 +1168,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -1167,11 +1176,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1187,9 +1196,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -1208,12 +1217,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -1221,9 +1230,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -1231,17 +1240,11 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", @@ -1258,9 +1261,9 @@ dependencies = [ [[package]] name = "hyper-http-proxy" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d06dbdfbacf34d996c6fb540a71a684a7aae9056c71951163af8a8a4c07b9a4" +checksum = "7ad4b0a1e37510028bc4ba81d0e38d239c39671b0f0ce9e02dfa93a8133f7c08" dependencies = [ "bytes", "futures-util", @@ -1278,16 +1281,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http", "hyper", "hyper-util", "log", - "rustls 0.23.19", + "rustls 0.23.25", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", @@ -1346,14 +1349,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -1408,9 +1412,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -1432,9 +1436,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -1453,9 +1457,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -1482,7 +1486,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -1525,9 +1529,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1565,9 +1569,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is_terminal_polyfill" @@ -1577,9 +1581,33 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] [[package]] name = "jobserver" @@ -1592,10 +1620,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1613,15 +1642,15 @@ dependencies = [ [[package]] name = "jsonpath-rust" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a61b87f6a55cc6c28fed5739dd36b9642321ce63e4a5e4a4715d69106f4a10" +checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b" dependencies = [ "pest", "pest_derive", "regex", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -1636,14 +1665,14 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.0" +version = "9.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "js-sys", "pem", - "ring 0.17.8", + "ring 0.17.14", "serde", "serde_json", "simple_asn1", @@ -1719,13 +1748,13 @@ dependencies = [ "k8s-openapi", "kube-core", "pem", - "rustls 0.23.19", + "rustls 0.23.25", "rustls-pemfile 2.2.0", "secrecy", "serde", "serde_json", "serde_yaml 0.9.34+deprecated", - "thiserror 2.0.9", + "thiserror 2.0.12", "tokio", "tokio-util", "tower", @@ -1748,7 +1777,7 @@ dependencies = [ "serde", "serde-value", "serde_json", - "thiserror 2.0.9", + "thiserror 2.0.12", ] [[package]] @@ -1761,7 +1790,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -1786,7 +1815,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror 2.0.9", + "thiserror 2.0.12", "tokio", "tokio-util", "tracing", @@ -1803,9 +1832,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libm" @@ -1819,16 +1848,16 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] [[package]] name = "libz-ng-sys" -version = "1.1.20" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0f7295a34685977acb2e8cc8b08ee4a8dffd6cf278eeccddbe1ed55ba815d5" +checksum = "a7118c2c2a3c7b6edc279a8b19507672b9c4d716f95e671172dfa4e23f9fd824" dependencies = [ "cmake", "libc", @@ -1842,15 +1871,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "lock_api" @@ -1864,15 +1893,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" -version = "0.12.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ "hashbrown 0.15.2", ] @@ -1906,23 +1935,22 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -1938,7 +1966,7 @@ dependencies = [ "bytes", "futures", "pin-project", - "rand", + "rand 0.8.5", "thiserror 1.0.69", "tokio", "tokio-util", @@ -1947,9 +1975,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -2009,7 +2037,7 @@ version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "filetime", "fsevent-sys", "inotify", @@ -2053,7 +2081,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "smallvec", "zeroize", ] @@ -2096,26 +2124,26 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -2132,20 +2160,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -2211,9 +2239,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" dependencies = [ "base64 0.22.1", "serde", @@ -2236,20 +2264,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.12", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" dependencies = [ "pest", "pest_generator", @@ -2257,22 +2285,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" dependencies = [ "once_cell", "pest", @@ -2281,29 +2309,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -2390,7 +2418,7 @@ dependencies = [ "pingora-runtime", "pingora-timeout", "prometheus", - "rand", + "rand 0.8.5", "regex", "serde", "serde_yaml 0.8.26", @@ -2448,7 +2476,7 @@ dependencies = [ "arrayvec", "hashbrown 0.15.2", "parking_lot", - "rand", + "rand 0.9.0", ] [[package]] @@ -2496,7 +2524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31a7c445ca224630961045684201e3cf8da9af0b01f286ed54ff8b2403aaabff" dependencies = [ "once_cell", - "rand", + "rand 0.8.5", "thread_local", "tokio", ] @@ -2537,9 +2565,24 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "powerfmt" @@ -2549,11 +2592,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.24", ] [[package]] @@ -2582,9 +2625,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -2612,37 +2655,39 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.19", + "rustls 0.23.25", "socket2", - "thiserror 2.0.9", + "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "getrandom", - "rand", - "ring 0.17.8", + "getrandom 0.3.2", + "rand 0.9.0", + "ring 0.17.14", "rustc-hash", - "rustls 0.23.19", + "rustls 0.23.25", "rustls-pki-types", "slab", - "thiserror 2.0.9", + "thiserror 2.0.12", "tinyvec", "tracing", "web-time", @@ -2650,27 +2695,33 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -2678,8 +2729,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.24", ] [[package]] @@ -2689,7 +2751,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2698,16 +2770,25 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", ] [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", ] [[package]] @@ -2716,7 +2797,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 1.0.69", ] @@ -2752,9 +2833,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.9" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", "bytes", @@ -2777,16 +2858,17 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.19", + "rustls 0.23.25", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-native-tls", "tokio-rustls", + "tower", "tower-service", "url", "wasm-bindgen", @@ -2813,15 +2895,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", - "spin 0.9.8", "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -2850,9 +2931,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" dependencies = [ "const-oid", "digest", @@ -2861,7 +2942,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "signature", "spki", "subtle", @@ -2870,9 +2951,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.36.0" +version = "1.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +checksum = "faa7de2ba56ac291bd90c6b9bece784a52ae1411f9506544b3eae36dd2356d50" dependencies = [ "arrayvec", "num-traits", @@ -2886,21 +2967,21 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.38.41" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2917,13 +2998,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "log", "once_cell", - "ring 0.17.8", + "ring 0.17.14", "rustls-pki-types", "rustls-webpki", "subtle", @@ -2952,7 +3033,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.0.1", + "security-framework 3.2.0", ] [[package]] @@ -2975,20 +3056,20 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" dependencies = [ "web-time", ] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ - "ring 0.17.8", + "ring 0.17.14", "rustls-pki-types", "untrusted 0.9.0", ] @@ -3001,7 +3082,7 @@ checksum = "a44822b10c095e574869de2b891e40c724fef42cadaea040d1cd3bdbb13d36a5" dependencies = [ "backtrace", "crossbeam-channel", - "rand", + "rand 0.8.5", "trackable 0.2.24", ] @@ -3014,7 +3095,7 @@ dependencies = [ "crossbeam-channel", "hostname", "percent-encoding", - "rand", + "rand 0.8.5", "rustracing", "thrift_codec", "trackable 0.2.24", @@ -3022,15 +3103,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -3052,9 +3133,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" dependencies = [ "dyn-clone", "schemars_derive", @@ -3064,14 +3145,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3086,7 +3167,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.8", + "ring 0.17.14", "untrusted 0.9.0", ] @@ -3105,7 +3186,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -3114,11 +3195,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "core-foundation 0.10.0", "core-foundation-sys", "libc", @@ -3127,9 +3208,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -3137,9 +3218,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] @@ -3156,13 +3237,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3173,16 +3254,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.8.0", "itoa", "memchr", "ryu", @@ -3212,15 +3293,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.8.0", "serde", "serde_derive", "serde_json", @@ -3230,14 +3311,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3258,7 +3339,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.8.0", "itoa", "ryu", "serde", @@ -3268,11 +3349,10 @@ dependencies = [ [[package]] name = "sfv" version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27daf6ed3fc7ffd5ea3ce9f684fe351c47e50f2fdbb6236e2bad0b440dbe408" +source = "git+https://github.com/undef1nd/sfv.git?tag=v0.9.4#e6499d8ce11271dd0a4c1f72445775a58b835a56" dependencies = [ "data-encoding", - "indexmap 2.6.0", + "indexmap 2.8.0", "rust_decimal", ] @@ -3329,18 +3409,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] name = "simple_asn1" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 1.0.69", + "thiserror 2.0.12", "time", ] @@ -3364,15 +3444,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3437,7 +3517,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3459,21 +3539,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -3491,17 +3565,17 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "tempfile" -version = "3.14.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -3518,9 +3592,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" [[package]] name = "thiserror" @@ -3533,11 +3607,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.9" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.9", + "thiserror-impl 2.0.12", ] [[package]] @@ -3548,18 +3622,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "thiserror-impl" -version = "2.0.9" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3584,9 +3658,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -3599,15 +3673,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -3625,9 +3699,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -3640,9 +3714,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.42.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -3658,13 +3732,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3684,18 +3758,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" dependencies = [ "pin-project", - "rand", + "rand 0.8.5", "tokio", ] [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.19", - "rustls-pki-types", + "rustls 0.23.25", "tokio", ] @@ -3725,9 +3798,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -3740,9 +3813,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -3761,11 +3834,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.8.0", "serde", "serde_spanned", "toml_datetime", @@ -3774,14 +3847,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", "tokio", "tokio-util", "tower-layer", @@ -3796,7 +3869,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "base64 0.22.1", - "bitflags 2.6.0", + "bitflags 2.9.0", "bytes", "http", "http-body", @@ -3839,7 +3912,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] @@ -3888,9 +3961,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "ucd-trie" @@ -3900,15 +3973,15 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unsafe-libyaml" @@ -3994,49 +4067,59 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4044,28 +4127,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -4087,15 +4173,15 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.8", + "ring 0.17.14", "untrusted 0.9.0", ] [[package]] name = "webpki-roots" -version = "0.26.7" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -4140,34 +4226,39 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + [[package]] name = "windows-registry" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result", "windows-strings", - "windows-targets 0.52.6", + "windows-targets 0.53.0", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -4245,13 +4336,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4270,6 +4377,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -4288,6 +4401,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -4306,12 +4425,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -4330,6 +4461,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -4348,6 +4485,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -4366,6 +4509,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -4384,15 +4533,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -4449,7 +4613,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", "synstructure", ] @@ -4459,8 +4623,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", ] [[package]] @@ -4471,27 +4643,38 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", "synstructure", ] @@ -4520,32 +4703,32 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.100", ] [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 759c43f..93ce989 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,3 +69,7 @@ style = { level = "warn", priority = -1 } module_name_repetitions = "allow" disallowed-macros = "deny" + +# workaround for pingora-core issue https://github.com/cloudflare/pingora/issues/568 +[patch.crates-io] +sfv = { git = "https://github.com/undef1nd/sfv.git", tag = "v0.9.4" } From 608b1c5838aa28a7c57924c1b74693b17b99a24f Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Mon, 31 Mar 2025 13:23:25 +0100 Subject: [PATCH 4/7] fix clippy errors --- src/child.rs | 4 ++-- src/identity/mod.rs | 17 +++++++++-------- src/main.rs | 8 ++------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/child.rs b/src/child.rs index b5f508e..8bafc08 100644 --- a/src/child.rs +++ b/src/child.rs @@ -42,7 +42,7 @@ async fn terminate(mut child: Child) { if exit_status.success() { trace!("Child process exited successfully"); } else { - warn!("Child process exited with status: {}", exit_status); + warn!("Child process exited with status: {exit_status}"); } } Err(e) => { @@ -97,7 +97,7 @@ impl Service for ChildService { if exit_status.success() { trace!("Child process exited successfully"); } else { - warn!("Child process exited with status: {}", exit_status); + warn!("Child process exited with status: {exit_status}"); } } Err(e) => { diff --git a/src/identity/mod.rs b/src/identity/mod.rs index 0342b2d..e16b311 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -189,13 +189,13 @@ impl Service for IdentitySyncService { async fn start(&mut self, mut shutdown: watch::Receiver) { // Write issuer at startup if let Err(e) = self.write_issuer().await { - warn!("Failed to write issuer: {}", e); + warn!("Failed to write issuer: {e}"); } if let Err(e) = self.provider.ensure_audience(&self.audience).await { warn!( - "Failed to create or verify API for audience {}: {}", - self.audience, e + "Failed to create or verify API for audience {audience}: {e}", + audience = self.audience, e = e ); } @@ -205,7 +205,7 @@ impl Service for IdentitySyncService { _ = shutdown.changed() => { // Clean up issuer file on shutdown if let Err(e) = dirs::delete_iss().await { - error!("Failed to delete issuer file: {}", e); + error!("Failed to delete issuer file: {e}"); } break; } @@ -214,7 +214,7 @@ impl Service for IdentitySyncService { Ok(token) => { match write_file_idempotent(&self.path, &token) { Ok(()) => { - trace!("Successfully wrote token for audience {} to file", self.audience); + trace!("Successfully wrote token for audience {audience} to file", audience = self.audience); match get_claims(&token) { Ok(claims) => { match serde_json::to_string_pretty(&claims) { @@ -224,16 +224,17 @@ impl Service for IdentitySyncService { } Err(e) => { error!("Failed to get claims for token: {e}"); - info!("Token prefix: {}", &token[..6]); + info!("Token prefix: {token_prefix}", token_prefix = &token[..6]); } } } Err(e) => { - error!("Failed to write token to file for audience {}: {}", self.audience, e); + error!("Failed to write token to file for audience {audience}: {e}", + audience = self.audience, e = e); } } } - Err(e) => error!("Failed to get token for audience {}: {}", self.audience, e), + Err(e) => error!("Failed to get token for audience {audience}: {e}", audience = self.audience, e = e), } } } diff --git a/src/main.rs b/src/main.rs index 3e320d0..5d1a5a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -562,11 +562,7 @@ fn maybe_run_background_ngrok( }); let url = runtime.block_on(async move { - if let Ok(url) = rx.await { - Some(url) - } else { - None - } + (rx.await).ok() }); return url; @@ -642,7 +638,7 @@ fn handle_run( wait_for_signals(&mut server, &mut file_rx, &mut should_exit).await?; } if let Err(e) = dirs::delete_url().await { - warn!("Failed to delete url: {}", e); + warn!("Failed to delete url: {e}"); } Ok(()) }) From 148089843aa17d8dcc34619a244c934e684cb139 Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Mon, 31 Mar 2025 17:49:21 +0100 Subject: [PATCH 5/7] write url in proper location --- src/main.rs | 52 +++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5d1a5a2..c210b0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -609,20 +609,36 @@ fn handle_run( if let Some(url) = ngrok_url.as_ref() { env::set_var("NGROK_URL", url); } - let url = if !app_config.url.is_empty() { - app_config.url.clone() - } else if let Some(ngrok_url) = ngrok_url { - ngrok_url - } else { - format!("http://localhost:{port}") - }; - let (_file_tx, mut file_rx) = setup_env_watcher()?; runtime.block_on(async { - dirs::write_url(url).await?; let mut should_exit = false; while !should_exit { let mut server = factor::server::Server::new_from_runtime(runtime.clone()); + dotenv().ok(); + + let reject_unknown = match env::var("REJECT_UNKNOWN") { + Ok(val) => { + let val = val.to_lowercase(); + matches!(val.as_str(), "true" | "t" | "yes" | "y" | "1" | "on") + } + Err(_) => reject_unknown, + }; + + let port = match env::var("PORT") { + Ok(val) => val.parse::().unwrap_or(port), + Err(_) => port, + }; + + let url = if !app_config.url.is_empty() { + app_config.url.clone() + } else if let Some(url) = ngrok_url.as_ref() { + url.clone() + } else { + format!("http://localhost:{port}") + }; + + dirs::write_url(url.clone()).await?; + add_services( &mut server, app_config, @@ -768,24 +784,6 @@ fn add_services( ipv6: bool, command: &[String], ) -> Result<(), anyhow::Error> { - // Load .env file variables into the environment - dotenv().ok(); - - // Check environment for overrides (this will include variables from .env) - let reject_unknown = match env::var("REJECT_UNKNOWN") { - Ok(val) => { - let val = val.to_lowercase(); - matches!(val.as_str(), "true" | "t" | "yes" | "y" | "1" | "on") - } - Err(_) => reject_unknown, // Fall back to command-line value - }; - - // Get PORT from environment if set - let port = match env::var("PORT") { - Ok(val) => val.parse::().unwrap_or(port), // Parse or fall back to command-line - Err(_) => port, // Use command-line value - }; - let incoming_identity = get_incoming_identity(incoming_identity)?; let id = app_config From 137b9a500e6b0d3b96d79c9b5bdf4c48aebf11f4 Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Mon, 31 Mar 2025 23:18:27 +0100 Subject: [PATCH 6/7] fix formatting and iat --- src/identity/mod.rs | 8 +++----- src/identity/providers/local.rs | 7 ++++--- src/main.rs | 4 +--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/identity/mod.rs b/src/identity/mod.rs index e16b311..0dbd29c 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -195,7 +195,7 @@ impl Service for IdentitySyncService { if let Err(e) = self.provider.ensure_audience(&self.audience).await { warn!( "Failed to create or verify API for audience {audience}: {e}", - audience = self.audience, e = e + audience = self.audience ); } @@ -214,7 +214,7 @@ impl Service for IdentitySyncService { Ok(token) => { match write_file_idempotent(&self.path, &token) { Ok(()) => { - trace!("Successfully wrote token for audience {audience} to file", audience = self.audience); + trace!("Successfully wrote token for audience {audience} to file", audience=self.audience); match get_claims(&token) { Ok(claims) => { match serde_json::to_string_pretty(&claims) { @@ -228,9 +228,7 @@ impl Service for IdentitySyncService { } } } - Err(e) => { - error!("Failed to write token to file for audience {audience}: {e}", - audience = self.audience, e = e); + Err(e) => {error!("Failed to write token to file for audience {audience}: {e}", audience=self.audience); } } } diff --git a/src/identity/providers/local.rs b/src/identity/providers/local.rs index 8b88811..2be64b9 100644 --- a/src/identity/providers/local.rs +++ b/src/identity/providers/local.rs @@ -127,6 +127,7 @@ struct Claims { iss: String, sub: String, aud: String, + iat: u64, exp: u64, } @@ -155,13 +156,13 @@ impl IdentityProvider for Provider { async fn get_token(&self, audience: &str) -> Result { let sub = self.config.sub.as_ref().context("Sub not configured")?; + let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); let claims = Claims { iss: self.get_iss().await?, sub: sub.to_string(), aud: audience.to_string(), - exp: (SystemTime::now() + std::time::Duration::from_secs(1800)) // Expiration time (30 minutes from now) - .duration_since(UNIX_EPOCH)? - .as_secs(), + iat: now, + exp: now + 1800, // Expiration time (30 minutes from now) }; let mut header = Header::new(Algorithm::RS256); header.kid = Some(self.kid.clone()); diff --git a/src/main.rs b/src/main.rs index c210b0c..3731a26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -561,9 +561,7 @@ fn maybe_run_background_ngrok( server.wait_for_exit(); }); - let url = runtime.block_on(async move { - (rx.await).ok() - }); + let url = runtime.block_on(async move { (rx.await).ok() }); return url; } From 2f6024355860a84196cf2d0e318b44dbd22373b2 Mon Sep 17 00:00:00 2001 From: Vishvananda Abrams Date: Mon, 31 Mar 2025 23:53:12 +0100 Subject: [PATCH 7/7] read port from env before starting ngrok --- src/main.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3731a26..aae8945 100644 --- a/src/main.rs +++ b/src/main.rs @@ -602,6 +602,12 @@ fn handle_run( } trace!("Running run command"); + dotenv().ok(); + let port = match env::var("PORT") { + Ok(val) => val.parse::().unwrap_or(port), + Err(_) => port, + }; + let runtime: Arc = Runtime::new()?.into(); let ngrok_url = maybe_run_background_ngrok(&runtime, app_config, port, ipv6); if let Some(url) = ngrok_url.as_ref() { @@ -622,11 +628,6 @@ fn handle_run( Err(_) => reject_unknown, }; - let port = match env::var("PORT") { - Ok(val) => val.parse::().unwrap_or(port), - Err(_) => port, - }; - let url = if !app_config.url.is_empty() { app_config.url.clone() } else if let Some(url) = ngrok_url.as_ref() {