Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ src/*.html

# SSL certificates
*.pem

/guest-profiles
/benchmark-results/**
534 changes: 534 additions & 0 deletions OPTIMIZATION.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
trusted-server-js = { path = "../js" }
url = { workspace = true }
urlencoding = { workspace = true }
Expand Down
18 changes: 15 additions & 3 deletions crates/common/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ fn rerun_if_changed() {
}

fn merge_toml() {
use config::{Config, Environment, File, FileFormat};

// Get the OUT_DIR where we'll copy the config file
let dest_path = Path::new(TRUSTED_SERVER_OUTPUT_CONFIG_PATH);

Expand All @@ -51,9 +53,19 @@ fn merge_toml() {
let toml_content = fs::read_to_string(init_config_path)
.unwrap_or_else(|_| panic!("Failed to read {:?}", init_config_path));

// For build time: use from_toml to parse with environment variables
let settings = settings::Settings::from_toml(&toml_content)
.expect("Failed to parse settings at build time");
// Merge TOML + TRUSTED_SERVER__* env vars at build time using the config crate.
// At runtime, from_toml() skips this — the embedded TOML is already resolved.
let environment = Environment::default()
.prefix(settings::ENVIRONMENT_VARIABLE_PREFIX)
.separator(settings::ENVIRONMENT_VARIABLE_SEPARATOR);
let config = Config::builder()
.add_source(File::from_str(&toml_content, FileFormat::Toml))
.add_source(environment)
.build()
.expect("Failed to build configuration at build time");
let settings: settings::Settings = config
.try_deserialize()
.expect("Failed to deserialize configuration at build time");

// Write the merged settings to the output directory as TOML
let merged_toml =
Expand Down
38 changes: 29 additions & 9 deletions crates/common/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::str;

#[cfg(test)]
use config::{Config, Environment, File, FileFormat};
use error_stack::{Report, ResultExt};
use regex::Regex;
Expand Down Expand Up @@ -357,13 +358,32 @@ impl Settings {

/// Creates a new [`Settings`] instance from a TOML string.
///
/// Parses the provided TOML configuration and applies any environment
/// variable overrides using the `TRUSTED_SERVER__` prefix.
/// Deserializes the TOML directly without scanning for environment variable
/// overrides. For build-time configuration that merges `TRUSTED_SERVER__*`
/// env vars, use [`Settings::from_toml_with_env`].
///
/// # Errors
///
/// - [`TrustedServerError::Configuration`] if the TOML is invalid or missing required fields
pub fn from_toml(toml_str: &str) -> Result<Self, Report<TrustedServerError>> {
let mut settings: Self =
toml::from_str(toml_str).change_context(TrustedServerError::Configuration {
message: "Failed to deserialize TOML configuration".to_string(),
})?;

settings.publisher.normalize();
Ok(settings)
}

/// Parses TOML and merges `TRUSTED_SERVER__*` environment variable overrides.
/// Test-only helper for verifying env var override behavior.
/// At build time, `build.rs::merge_toml()` performs this merging directly.
///
/// # Errors
///
/// - [`TrustedServerError::Configuration`] if the TOML is invalid or env var merging fails
#[cfg(test)]
pub fn from_toml_with_env(toml_str: &str) -> Result<Self, Report<TrustedServerError>> {
let environment = Environment::default()
.prefix(ENVIRONMENT_VARIABLE_PREFIX)
.separator(ENVIRONMENT_VARIABLE_SEPARATOR);
Expand Down Expand Up @@ -709,7 +729,7 @@ mod tests {
Some("https://origin.test-publisher.com"),
|| {
temp_env::with_var(env_key, Some("[\"smartadserver\",\"rubicon\"]"), || {
let res = Settings::from_toml(&toml_str);
let res = Settings::from_toml_with_env(&toml_str);
if res.is_err() {
eprintln!("JSON override error: {:?}", res.as_ref().err());
}
Expand Down Expand Up @@ -761,7 +781,7 @@ mod tests {
|| {
temp_env::with_var(env_key0, Some("smartadserver"), || {
temp_env::with_var(env_key1, Some("openx"), || {
let res = Settings::from_toml(&toml_str);
let res = Settings::from_toml_with_env(&toml_str);
if res.is_err() {
eprintln!("Indexed override error: {:?}", res.as_ref().err());
}
Expand Down Expand Up @@ -820,7 +840,7 @@ mod tests {
temp_env::with_var(path_key, Some("^/env-handler"), || {
temp_env::with_var(username_key, Some("env-user"), || {
temp_env::with_var(password_key, Some("env-pass"), || {
let settings = Settings::from_toml(&toml_str)
let settings = Settings::from_toml_with_env(&toml_str)
.expect("Settings should load from env");
assert_eq!(settings.handlers.len(), 1);
let handler = &settings.handlers[0];
Expand All @@ -846,7 +866,7 @@ mod tests {
env_key,
Some(r#"{"X-Robots-Tag": "noindex", "X-Custom-Header": "custom value"}"#),
|| {
let settings = Settings::from_toml(&toml_str)
let settings = Settings::from_toml_with_env(&toml_str)
.expect("Settings should parse with JSON response_headers env");
assert_eq!(settings.response_headers.len(), 2);
assert_eq!(
Expand Down Expand Up @@ -880,7 +900,7 @@ mod tests {
),
Some("https://change-publisher.com"),
|| {
let settings = Settings::from_toml(&crate_test_settings_str());
let settings = Settings::from_toml_with_env(&crate_test_settings_str());

assert!(settings.is_ok(), "Settings should load from embedded TOML");
assert_eq!(
Expand All @@ -904,7 +924,7 @@ mod tests {
),
Some("https://change-publisher.com"),
|| {
let settings = Settings::from_toml(&toml_str);
let settings = Settings::from_toml_with_env(&toml_str);

assert!(settings.is_ok(), "Settings should load from embedded TOML");
assert_eq!(
Expand Down Expand Up @@ -1009,7 +1029,7 @@ mod tests {
temp_env::with_var(timeout_key, Some("2500"), || {
temp_env::with_var(rewrite_key, Some("true"), || {
temp_env::with_var(enabled_key, Some("true"), || {
let settings = Settings::from_toml(&toml_str)
let settings = Settings::from_toml_with_env(&toml_str)
.expect("Settings should load");

let config = settings
Expand Down
Loading