Skip to content
Merged
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
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2025-10-14

### Changed
- Publisher origin backend now uses `publisher.origin_url` to dynamically create backends, deprecated `publisher.origin_backend` field
- Prebid backend now uses `prebid.server_url` to dynamically create backends, deprecated `prebid.prebid_backend` field
- Removed static backend definitions from `fastly.toml` for publisher and prebid

### Added
- Added `.rust-analyzer.json` for improved development environment support with Neovim/rust-analyzer

## [1.1.0] - 2025-10-05

### Added
Expand Down Expand Up @@ -82,7 +92,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial implementation of Trusted Server

[Unreleased]:https://github.com/IABTechLab/trusted-server/compare/v1.0.6...HEAD
[Unreleased]:https://github.com/IABTechLab/trusted-server/compare/v1.2.0...HEAD
[1.2.0]:https://github.com/IABTechLab/trusted-server/compare/v1.1.0...v1.2.0
[1.1.0]:https://github.com/IABTechLab/trusted-server/compare/v1.0.6...v1.1.0
[1.0.6]:https://github.com/IABTechLab/trusted-server/compare/v1.0.5...v1.0.6
[1.0.5]:https://github.com/IABTechLab/trusted-server/compare/v1.0.4...v1.0.5
[1.0.4]:https://github.com/IABTechLab/trusted-server/compare/v1.0.3...v1.0.4
Expand Down
18 changes: 17 additions & 1 deletion crates/common/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::time::Duration;

use error_stack::Report;
use error_stack::{Report, ResultExt};
use fastly::backend::Backend;
use url::Url;

use crate::error::TrustedServerError;

Expand Down Expand Up @@ -66,6 +67,21 @@ pub fn ensure_origin_backend(
}
}
}
pub fn ensure_backend_from_url(origin_url: &str) -> Result<String, Report<TrustedServerError>> {
let parsed_url = Url::parse(origin_url).change_context(TrustedServerError::Proxy {
message: format!("Invalid origin_url: {}", origin_url),
})?;

let scheme = parsed_url.scheme();
let host = parsed_url.host_str().ok_or_else(|| {
Report::new(TrustedServerError::Proxy {
message: "Missing host in origin_url".to_string(),
})
})?;
let port = parsed_url.port();

ensure_origin_backend(scheme, host, port)
}

#[cfg(test)]
mod tests {
Expand Down
14 changes: 11 additions & 3 deletions crates/common/src/prebid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use fastly::http::{header, Method, StatusCode};
use fastly::{Error, Request, Response};
use serde_json::json;

use crate::backend::ensure_backend_from_url;
use crate::constants::{
HEADER_SYNTHETIC_FRESH, HEADER_SYNTHETIC_TRUSTED_SERVER, HEADER_X_COMPRESS_HINT,
HEADER_X_CONSENT_ADVERTISING, HEADER_X_FORWARDED_FOR,
Expand Down Expand Up @@ -194,10 +195,17 @@ impl PrebidRequest {
id
);

req.set_body_json(&prebid_body)?;
// TrustedServerError doesn't implement std::error::Error
match ensure_backend_from_url(&settings.prebid.server_url) {
Ok(backend_name) => {
req.set_body_json(&prebid_body)?;

let resp = req.send("prebid_backend")?;
Ok(resp)
let resp = req.send(backend_name)?;
Ok(resp)
}

Err(e) => fastly::error::bail!("Could not get prebid backend: {}", e),
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions crates/common/src/prebid_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use fastly::http::{header, Method, StatusCode};
use fastly::{Request, Response};
use serde_json::{json, Value};

use crate::backend::ensure_backend_from_url;
use crate::constants::{HEADER_SYNTHETIC_FRESH, HEADER_SYNTHETIC_TRUSTED_SERVER};
use crate::error::TrustedServerError;
use crate::gdpr::get_consent_from_request;
Expand Down Expand Up @@ -78,10 +79,12 @@ pub async fn handle_prebid_auction(

log::info!("Sending request to Prebid Server");

let backend_name = ensure_backend_from_url(&settings.prebid.server_url)?;

// 5. Send to PBS and get response
let mut pbs_response =
pbs_req
.send("prebid_backend")
.send(backend_name)
.change_context(TrustedServerError::Prebid {
message: "Failed to send request to Prebid Server".to_string(),
})?;
Expand Down Expand Up @@ -175,9 +178,12 @@ pub async fn handle_prebid_cookie_sync(
})?;

// 4. Get response and transform sync URLs

let backend_name = ensure_backend_from_url(&settings.prebid.server_url)?;

let mut pbs_response =
pbs_req
.send("prebid_backend")
.send(backend_name)
.change_context(TrustedServerError::Prebid {
message: "Failed to send cookie sync request".to_string(),
})?;
Expand Down
14 changes: 9 additions & 5 deletions crates/common/src/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use error_stack::{Report, ResultExt};
use fastly::http::{header, StatusCode};
use fastly::{Body, Request, Response};

use crate::backend::ensure_backend_from_url;
use crate::http_util::serve_static_with_etag;

use crate::constants::{
Expand Down Expand Up @@ -359,17 +360,20 @@ pub fn handle_publisher_request(
has_synthetic_cookie
);

// Extract host from the origin_url using the Publisher's origin_host method
let backend_name = ensure_backend_from_url(&settings.publisher.origin_url)?;
let origin_host = settings.publisher.origin_host();

log::info!("Setting host header to: {}", origin_host);
log::info!(
"Proxying to dynamic backend: {} (from {})",
backend_name,
settings.publisher.origin_url
);
req.set_header("host", &origin_host);

// Send the request to the origin backend
let mut response = req
.send(&settings.publisher.origin_backend)
.send(&backend_name)
.change_context(TrustedServerError::Proxy {
message: "Failed to proxy request".to_string(),
message: "Failed to proxy request to origin".to_string(),
})?;

// Log all response headers for debugging
Expand Down
8 changes: 0 additions & 8 deletions crates/common/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ pub struct AdServer {
pub struct Publisher {
pub domain: String,
pub cookie_domain: String,
pub origin_backend: String,
pub origin_url: String,
/// Secret used to encrypt/decrypt proxied URLs in `/first-party/proxy`.
/// Keep this secret stable to allow existing links to decode.
Expand All @@ -38,7 +37,6 @@ impl Publisher {
/// let publisher = Publisher {
/// domain: "example.com".to_string(),
/// cookie_domain: ".example.com".to_string(),
/// origin_backend: "edgepubs_main_be".to_string(),
/// origin_url: "https://origin.example.com:8080".to_string(),
/// proxy_secret: "proxy-secret".to_string(),
/// };
Expand Down Expand Up @@ -530,7 +528,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "https://origin.example.com:8080".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand All @@ -540,7 +537,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "https://origin.example.com".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand All @@ -550,7 +546,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "http://localhost:9090".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand All @@ -560,7 +555,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "localhost:9090".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand All @@ -570,7 +564,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "http://192.168.1.1:8080".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand All @@ -580,7 +573,6 @@ mod tests {
let publisher = Publisher {
domain: "example.com".to_string(),
cookie_domain: ".example.com".to_string(),
origin_backend: "publisher_origin".to_string(),
origin_url: "http://[::1]:8080".to_string(),
proxy_secret: "test-secret".to_string(),
};
Expand Down
7 changes: 1 addition & 6 deletions fastly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ build = """

[local_server.backends.equativ_ad_api_2]
url = "https://adapi-srv-eu.smartadserver.com"
[local_server.backends.prebid_backend]
url = "http://68.183.113.79:8000"

[local_server.backends.gam_backend]
url = "https://securepubads.g.doubleclick.net"
[local_server.backends.wordpress_backend]
Expand All @@ -67,10 +66,6 @@ build = """
[local_server.backends.googleads_doubleclick_backend]
url = "https://securepubads.g.doubleclick.net"

[local_server.backends.publisher_origin]
url = "http://localhost:9090"
override_host = "localhost:9090"

# Backend for proxying ad creatives and tracking pixels
[local_server.backends.ad_cdn_backend]
url = "https://cdn.adsrvr.org" # Default, will be overridden dynamically
Expand Down
1 change: 0 additions & 1 deletion trusted-server.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ sync_url = "https://adapi-srv-eu.smartadserver.com/ac?pgid=2040327&fmtid=137675&
[publisher]
domain = "test-publisher.com"
cookie_domain = ".test-publisher.com"
origin_backend = "publisher_origin"
origin_url = "https://origin.test-publisher.com"
proxy_secret = "change-me-proxy-secret"

Expand Down