From 51f6fc71c0d7899c1259bd4040b1c34b0fe45f03 Mon Sep 17 00:00:00 2001 From: prk-Jr Date: Fri, 6 Feb 2026 18:24:23 +0530 Subject: [PATCH 1/6] Set x-synthetic-id header on integration routes Integration proxy responses were missing the x-synthetic-id header because handle_proxy dispatched to integrations without adding it. This caused identity tracking to break for first-party re-hosted integrations like Permutive's secure-signal endpoint. Centralizing the header logic in handle_proxy ensures all current and future integrations automatically include the synthetic ID, rather than requiring each integration to implement it manually. Fixes #205 --- crates/common/src/integrations/registry.rs | 246 +++++++++++++++++++- crates/common/src/integrations/testlight.rs | 2 - trusted-server.toml | 5 - 3 files changed, 244 insertions(+), 9 deletions(-) diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs index 7fe9e77..d2449d6 100644 --- a/crates/common/src/integrations/registry.rs +++ b/crates/common/src/integrations/registry.rs @@ -4,12 +4,15 @@ use std::sync::{Arc, Mutex}; use async_trait::async_trait; use error_stack::Report; -use fastly::http::Method; +use fastly::http::{header, Method}; use fastly::{Request, Response}; use matchit::Router; +use crate::constants::{COOKIE_SYNTHETIC_ID, HEADER_X_SYNTHETIC_ID}; +use crate::cookies::create_synthetic_cookie; use crate::error::TrustedServerError; use crate::settings::Settings; +use crate::synthetic::get_or_generate_synthetic_id; /// Action returned by attribute rewriters to describe how the runtime should mutate the element. #[derive(Debug, Clone, PartialEq, Eq)] @@ -602,6 +605,9 @@ impl IntegrationRegistry { } /// Dispatch a proxy request when an integration handles the path. + /// + /// This method automatically sets the `x-synthetic-id` header and + /// `synthetic_id` cookie on successful responses. #[must_use] pub async fn handle_proxy( &self, @@ -611,7 +617,35 @@ impl IntegrationRegistry { req: Request, ) -> Option>> { if let Some((proxy, _)) = self.find_route(method, path) { - Some(proxy.handle(settings, req).await) + // Generate synthetic ID before consuming request + let synthetic_id_result = get_or_generate_synthetic_id(settings, &req); + let has_synthetic_cookie = req + .get_header(header::COOKIE) + .and_then(|h| h.to_str().ok()) + .map(|cookies| { + cookies.split(';').any(|cookie| { + cookie + .trim_start() + .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) + }) + }) + .unwrap_or(false); + + let mut result = proxy.handle(settings, req).await; + + // Set synthetic ID header on successful responses + if let Ok(ref mut response) = result { + if let Ok(ref synthetic_id) = synthetic_id_result { + response.set_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); + if !has_synthetic_cookie { + response.set_header( + header::SET_COOKIE, + create_synthetic_cookie(settings, synthetic_id.as_str()), + ); + } + } + } + Some(result) } else { None } @@ -1042,4 +1076,212 @@ mod tests { assert!(!registry.has_route(&Method::GET, "/integrations/test/users")); assert!(!registry.has_route(&Method::POST, "/integrations/test/users")); } + + // Tests for synthetic ID header on proxy responses + + #[test] + fn cookie_detection_finds_synthetic_id() { + let cookies = "other=value; synthetic_id=abc123; more=stuff"; + let has_cookie = cookies.split(';').any(|cookie| { + cookie + .trim_start() + .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) + }); + assert!(has_cookie, "Should detect synthetic_id cookie"); + } + + #[test] + fn cookie_detection_handles_missing_cookie() { + let cookies = "other=value; session=xyz"; + let has_cookie = cookies.split(';').any(|cookie| { + cookie + .trim_start() + .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) + }); + assert!(!has_cookie, "Should not find synthetic_id when missing"); + } + + #[test] + fn cookie_detection_handles_empty_cookies() { + let cookies = ""; + let has_cookie = cookies.split(';').any(|cookie| { + cookie + .trim_start() + .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) + }); + assert!(!has_cookie, "Should handle empty cookie string"); + } + + // Async tests for handle_proxy synthetic ID functionality + + use crate::test_support::tests::create_test_settings; + + /// Mock proxy that returns a simple 200 OK response + struct SyntheticIdTestProxy; + + #[async_trait(?Send)] + impl IntegrationProxy for SyntheticIdTestProxy { + fn integration_name(&self) -> &'static str { + "synthetic_id_test" + } + + fn routes(&self) -> Vec { + vec![ + IntegrationEndpoint { + method: Method::GET, + path: "/integrations/test/synthetic".to_string(), + }, + IntegrationEndpoint { + method: Method::POST, + path: "/integrations/test/synthetic".to_string(), + }, + ] + } + + async fn handle( + &self, + _settings: &Settings, + _req: Request, + ) -> Result> { + // Return a simple response without the synthetic ID header. + // The registry's handle_proxy should add it. + Ok(Response::from_status(fastly::http::StatusCode::OK).with_body("test response")) + } + } + + #[test] + fn handle_proxy_sets_synthetic_id_header_on_response() { + let settings = create_test_settings(); + let routes = vec![( + Method::GET, + "/integrations/test/synthetic", + ( + Arc::new(SyntheticIdTestProxy) as Arc, + "synthetic_id_test", + ), + )]; + let registry = IntegrationRegistry::from_routes(routes); + + // Create a request without a synthetic ID cookie + let req = Request::get("https://test-publisher.com/integrations/test/synthetic"); + + // Call handle_proxy (uses futures executor in test environment) + let result = futures::executor::block_on(registry.handle_proxy( + &Method::GET, + "/integrations/test/synthetic", + &settings, + req, + )); + + // Should have matched and returned a response + assert!(result.is_some(), "Should find route and handle request"); + let response = result.unwrap(); + assert!(response.is_ok(), "Handler should succeed"); + + let response = response.unwrap(); + + // Verify x-synthetic-id header is present + assert!( + response.get_header(HEADER_X_SYNTHETIC_ID).is_some(), + "Response should have x-synthetic-id header" + ); + + // Verify Set-Cookie header is present (since no cookie was in request) + let set_cookie = response.get_header(header::SET_COOKIE); + assert!( + set_cookie.is_some(), + "Response should have Set-Cookie header for synthetic_id" + ); + + let cookie_value = set_cookie.unwrap().to_str().unwrap(); + assert!( + cookie_value.contains(COOKIE_SYNTHETIC_ID), + "Set-Cookie should contain synthetic_id cookie, got: {}", + cookie_value + ); + } + + #[test] + fn handle_proxy_skips_cookie_when_already_present() { + let settings = create_test_settings(); + let routes = vec![( + Method::GET, + "/integrations/test/synthetic", + ( + Arc::new(SyntheticIdTestProxy) as Arc, + "synthetic_id_test", + ), + )]; + let registry = IntegrationRegistry::from_routes(routes); + + // Create a request WITH an existing synthetic_id cookie + let mut req = Request::get("https://test-publisher.com/integrations/test/synthetic"); + req.set_header(header::COOKIE, "synthetic_id=existing_id_12345"); + + let result = futures::executor::block_on(registry.handle_proxy( + &Method::GET, + "/integrations/test/synthetic", + &settings, + req, + )); + + assert!(result.is_some(), "Should find route"); + let response = result.unwrap(); + assert!(response.is_ok(), "Handler should succeed"); + + let response = response.unwrap(); + + // Should still have x-synthetic-id header + assert!( + response.get_header(HEADER_X_SYNTHETIC_ID).is_some(), + "Response should still have x-synthetic-id header" + ); + + // But should NOT set the cookie again (it's already present) + let set_cookie = response.get_header(header::SET_COOKIE); + + // Either no Set-Cookie, or if present, not for synthetic_id + if let Some(cookie) = set_cookie { + let cookie_str = cookie.to_str().unwrap_or(""); + assert!( + !cookie_str.contains(COOKIE_SYNTHETIC_ID), + "Should not set duplicate synthetic_id cookie, got: {}", + cookie_str + ); + } + } + + #[test] + fn handle_proxy_works_with_post_method() { + let settings = create_test_settings(); + let routes = vec![( + Method::POST, + "/integrations/test/synthetic", + ( + Arc::new(SyntheticIdTestProxy) as Arc, + "synthetic_id_test", + ), + )]; + let registry = IntegrationRegistry::from_routes(routes); + + let req = Request::post("https://test-publisher.com/integrations/test/synthetic") + .with_body("test body"); + + let result = futures::executor::block_on(registry.handle_proxy( + &Method::POST, + "/integrations/test/synthetic", + &settings, + req, + )); + + assert!(result.is_some(), "Should find POST route"); + let response = result.unwrap(); + assert!(response.is_ok(), "Handler should succeed"); + + let response = response.unwrap(); + assert!( + response.get_header(HEADER_X_SYNTHETIC_ID).is_some(), + "POST response should have x-synthetic-id header" + ); + } } diff --git a/crates/common/src/integrations/testlight.rs b/crates/common/src/integrations/testlight.rs index b6883ac..8dd3ec7 100644 --- a/crates/common/src/integrations/testlight.rs +++ b/crates/common/src/integrations/testlight.rs @@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use validator::Validate; -use crate::constants::HEADER_X_SYNTHETIC_ID; use crate::error::TrustedServerError; use crate::integrations::{ AttributeRewriteAction, IntegrationAttributeContext, IntegrationAttributeRewriter, @@ -175,7 +174,6 @@ impl IntegrationProxy for TestlightIntegration { } } - response.set_header(HEADER_X_SYNTHETIC_ID, &synthetic_id); Ok(response) } } diff --git a/trusted-server.toml b/trusted-server.toml index 2e22c06..daa0214 100644 --- a/trusted-server.toml +++ b/trusted-server.toml @@ -21,11 +21,6 @@ secret_key = "trusted-server" # - "random_uuid" template = "{{ client_ip }}:{{ user_agent }}:{{ accept_language }}:{{ accept_encoding }}" -# Custom headers to be included in every response -# Allows publishers to include tags such as X-Robots-Tag: noindex -# [response_headers] -# X-Custom-Header = "custom header value" - # Request Signing Configuration # Enable signing of OpenRTB requests and other API calls [request_signing] From a0d22b2672df359f409665fcb9b6a6bbc529fa34 Mon Sep 17 00:00:00 2001 From: prk-Jr Date: Sat, 7 Feb 2026 08:32:05 +0530 Subject: [PATCH 2/6] Use cookie.rs utilities for synthetic ID detection Replaces inline cookie parsing with handle_request_cookies() and parse_cookies_to_jar() from cookies.rs for consistency. --- crates/common/src/integrations/registry.rs | 62 +++++++++------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs index d2449d6..e3c611b 100644 --- a/crates/common/src/integrations/registry.rs +++ b/crates/common/src/integrations/registry.rs @@ -9,7 +9,7 @@ use fastly::{Request, Response}; use matchit::Router; use crate::constants::{COOKIE_SYNTHETIC_ID, HEADER_X_SYNTHETIC_ID}; -use crate::cookies::create_synthetic_cookie; +use crate::cookies::{create_synthetic_cookie, handle_request_cookies}; use crate::error::TrustedServerError; use crate::settings::Settings; use crate::synthetic::get_or_generate_synthetic_id; @@ -619,16 +619,10 @@ impl IntegrationRegistry { if let Some((proxy, _)) = self.find_route(method, path) { // Generate synthetic ID before consuming request let synthetic_id_result = get_or_generate_synthetic_id(settings, &req); - let has_synthetic_cookie = req - .get_header(header::COOKIE) - .and_then(|h| h.to_str().ok()) - .map(|cookies| { - cookies.split(';').any(|cookie| { - cookie - .trim_start() - .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) - }) - }) + let has_synthetic_cookie = handle_request_cookies(&req) + .ok() + .flatten() + .and_then(|jar| jar.get(COOKIE_SYNTHETIC_ID).map(|_| true)) .unwrap_or(false); let mut result = proxy.handle(settings, req).await; @@ -1079,43 +1073,39 @@ mod tests { // Tests for synthetic ID header on proxy responses + use crate::cookies::parse_cookies_to_jar; + use crate::test_support::tests::create_test_settings; + #[test] - fn cookie_detection_finds_synthetic_id() { + fn cookie_jar_finds_synthetic_id() { let cookies = "other=value; synthetic_id=abc123; more=stuff"; - let has_cookie = cookies.split(';').any(|cookie| { - cookie - .trim_start() - .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) - }); - assert!(has_cookie, "Should detect synthetic_id cookie"); + let jar = parse_cookies_to_jar(cookies); + assert!( + jar.get(COOKIE_SYNTHETIC_ID).is_some(), + "Should detect synthetic_id cookie" + ); } #[test] - fn cookie_detection_handles_missing_cookie() { + fn cookie_jar_handles_missing_cookie() { let cookies = "other=value; session=xyz"; - let has_cookie = cookies.split(';').any(|cookie| { - cookie - .trim_start() - .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) - }); - assert!(!has_cookie, "Should not find synthetic_id when missing"); + let jar = parse_cookies_to_jar(cookies); + assert!( + jar.get(COOKIE_SYNTHETIC_ID).is_none(), + "Should not find synthetic_id when missing" + ); } #[test] - fn cookie_detection_handles_empty_cookies() { + fn cookie_jar_handles_empty_cookies() { let cookies = ""; - let has_cookie = cookies.split(';').any(|cookie| { - cookie - .trim_start() - .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) - }); - assert!(!has_cookie, "Should handle empty cookie string"); + let jar = parse_cookies_to_jar(cookies); + assert!( + jar.get(COOKIE_SYNTHETIC_ID).is_none(), + "Should handle empty cookie string" + ); } - // Async tests for handle_proxy synthetic ID functionality - - use crate::test_support::tests::create_test_settings; - /// Mock proxy that returns a simple 200 OK response struct SyntheticIdTestProxy; From be2c8aeb74c96168e509c582a509a4873ca7bc89 Mon Sep 17 00:00:00 2001 From: prk-Jr <49094961+prk-Jr@users.noreply.github.com> Date: Tue, 10 Feb 2026 02:50:03 +0530 Subject: [PATCH 3/6] Added X-Customer-Header Had deleted the comment accidentally but was needed already --- trusted-server.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/trusted-server.toml b/trusted-server.toml index daa0214..2e22c06 100644 --- a/trusted-server.toml +++ b/trusted-server.toml @@ -21,6 +21,11 @@ secret_key = "trusted-server" # - "random_uuid" template = "{{ client_ip }}:{{ user_agent }}:{{ accept_language }}:{{ accept_encoding }}" +# Custom headers to be included in every response +# Allows publishers to include tags such as X-Robots-Tag: noindex +# [response_headers] +# X-Custom-Header = "custom header value" + # Request Signing Configuration # Enable signing of OpenRTB requests and other API calls [request_signing] From a58f612127323e406a17adb2dfdaf8c66eb6a7f3 Mon Sep 17 00:00:00 2001 From: prk-Jr Date: Tue, 10 Feb 2026 21:55:59 +0530 Subject: [PATCH 4/6] Change synthetic ID header to append instead of set on responses --- crates/common/src/integrations/registry.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs index e3c611b..ff97b13 100644 --- a/crates/common/src/integrations/registry.rs +++ b/crates/common/src/integrations/registry.rs @@ -630,9 +630,9 @@ impl IntegrationRegistry { // Set synthetic ID header on successful responses if let Ok(ref mut response) = result { if let Ok(ref synthetic_id) = synthetic_id_result { - response.set_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); + response.append_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); if !has_synthetic_cookie { - response.set_header( + response.append_header( header::SET_COOKIE, create_synthetic_cookie(settings, synthetic_id.as_str()), ); From c0f9137a2972a2dec33f33158305fcd803e25077 Mon Sep 17 00:00:00 2001 From: prk-Jr Date: Tue, 10 Feb 2026 22:28:57 +0530 Subject: [PATCH 5/6] Set x-synthetic-id header on successful responses instead of appending --- crates/common/src/integrations/registry.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs index ff97b13..e4fc15c 100644 --- a/crates/common/src/integrations/registry.rs +++ b/crates/common/src/integrations/registry.rs @@ -630,7 +630,7 @@ impl IntegrationRegistry { // Set synthetic ID header on successful responses if let Ok(ref mut response) = result { if let Ok(ref synthetic_id) = synthetic_id_result { - response.append_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); + response.set_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); if !has_synthetic_cookie { response.append_header( header::SET_COOKIE, From cfc466ba239aceebc0a7b75122f417d260b1257a Mon Sep 17 00:00:00 2001 From: prk-Jr Date: Wed, 11 Feb 2026 17:02:14 +0530 Subject: [PATCH 6/6] Introduce helper and ensure the synthetic ID cookie is always set on responses --- crates/common/src/cookies.rs | 15 ++++ crates/common/src/integrations/registry.rs | 81 ++++++---------------- crates/common/src/publisher.rs | 28 ++------ 3 files changed, 40 insertions(+), 84 deletions(-) diff --git a/crates/common/src/cookies.rs b/crates/common/src/cookies.rs index 7511ed2..238424c 100644 --- a/crates/common/src/cookies.rs +++ b/crates/common/src/cookies.rs @@ -71,6 +71,21 @@ pub fn create_synthetic_cookie(settings: &Settings, synthetic_id: &str) -> Strin ) } +/// Sets the synthetic ID cookie on the given response. +/// +/// This helper abstracts the logic of creating the cookie string and appending +/// the Set-Cookie header to the response. +pub fn set_synthetic_cookie( + settings: &Settings, + response: &mut fastly::Response, + synthetic_id: &str, +) { + response.append_header( + header::SET_COOKIE, + create_synthetic_cookie(settings, synthetic_id), + ); +} + #[cfg(test)] mod tests { use crate::test_support::tests::create_test_settings; diff --git a/crates/common/src/integrations/registry.rs b/crates/common/src/integrations/registry.rs index e4fc15c..bf9fddf 100644 --- a/crates/common/src/integrations/registry.rs +++ b/crates/common/src/integrations/registry.rs @@ -4,12 +4,11 @@ use std::sync::{Arc, Mutex}; use async_trait::async_trait; use error_stack::Report; -use fastly::http::{header, Method}; +use fastly::http::Method; use fastly::{Request, Response}; use matchit::Router; -use crate::constants::{COOKIE_SYNTHETIC_ID, HEADER_X_SYNTHETIC_ID}; -use crate::cookies::{create_synthetic_cookie, handle_request_cookies}; +use crate::constants::HEADER_X_SYNTHETIC_ID; use crate::error::TrustedServerError; use crate::settings::Settings; use crate::synthetic::get_or_generate_synthetic_id; @@ -619,11 +618,6 @@ impl IntegrationRegistry { if let Some((proxy, _)) = self.find_route(method, path) { // Generate synthetic ID before consuming request let synthetic_id_result = get_or_generate_synthetic_id(settings, &req); - let has_synthetic_cookie = handle_request_cookies(&req) - .ok() - .flatten() - .and_then(|jar| jar.get(COOKIE_SYNTHETIC_ID).map(|_| true)) - .unwrap_or(false); let mut result = proxy.handle(settings, req).await; @@ -631,12 +625,7 @@ impl IntegrationRegistry { if let Ok(ref mut response) = result { if let Ok(ref synthetic_id) = synthetic_id_result { response.set_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); - if !has_synthetic_cookie { - response.append_header( - header::SET_COOKIE, - create_synthetic_cookie(settings, synthetic_id.as_str()), - ); - } + crate::cookies::set_synthetic_cookie(settings, response, synthetic_id.as_str()); } } Some(result) @@ -1072,39 +1061,9 @@ mod tests { } // Tests for synthetic ID header on proxy responses - - use crate::cookies::parse_cookies_to_jar; + use crate::constants::COOKIE_SYNTHETIC_ID; use crate::test_support::tests::create_test_settings; - - #[test] - fn cookie_jar_finds_synthetic_id() { - let cookies = "other=value; synthetic_id=abc123; more=stuff"; - let jar = parse_cookies_to_jar(cookies); - assert!( - jar.get(COOKIE_SYNTHETIC_ID).is_some(), - "Should detect synthetic_id cookie" - ); - } - - #[test] - fn cookie_jar_handles_missing_cookie() { - let cookies = "other=value; session=xyz"; - let jar = parse_cookies_to_jar(cookies); - assert!( - jar.get(COOKIE_SYNTHETIC_ID).is_none(), - "Should not find synthetic_id when missing" - ); - } - - #[test] - fn cookie_jar_handles_empty_cookies() { - let cookies = ""; - let jar = parse_cookies_to_jar(cookies); - assert!( - jar.get(COOKIE_SYNTHETIC_ID).is_none(), - "Should handle empty cookie string" - ); - } + use fastly::http::header; /// Mock proxy that returns a simple 200 OK response struct SyntheticIdTestProxy; @@ -1192,20 +1151,21 @@ mod tests { } #[test] - fn handle_proxy_skips_cookie_when_already_present() { + fn handle_proxy_always_sets_cookie() { let settings = create_test_settings(); let routes = vec![( Method::GET, "/integrations/test/synthetic", ( Arc::new(SyntheticIdTestProxy) as Arc, - "synthetic_id_test", + "test", ), )]; + let registry = IntegrationRegistry::from_routes(routes); - // Create a request WITH an existing synthetic_id cookie - let mut req = Request::get("https://test-publisher.com/integrations/test/synthetic"); + let mut req = Request::get("https://test.example.com/integrations/test/synthetic"); + // Pre-existing cookie req.set_header(header::COOKIE, "synthetic_id=existing_id_12345"); let result = futures::executor::block_on(registry.handle_proxy( @@ -1213,13 +1173,10 @@ mod tests { "/integrations/test/synthetic", &settings, req, - )); - - assert!(result.is_some(), "Should find route"); - let response = result.unwrap(); - assert!(response.is_ok(), "Handler should succeed"); + )) + .expect("should handle proxy request"); - let response = response.unwrap(); + let response = result.expect("proxy handle should succeed"); // Should still have x-synthetic-id header assert!( @@ -1227,15 +1184,19 @@ mod tests { "Response should still have x-synthetic-id header" ); - // But should NOT set the cookie again (it's already present) + // Should ALWAYS set the cookie again (per new requirements) let set_cookie = response.get_header(header::SET_COOKIE); - // Either no Set-Cookie, or if present, not for synthetic_id + assert!( + set_cookie.is_some(), + "Should set Set-Cookie header even if cookie is present" + ); + if let Some(cookie) = set_cookie { let cookie_str = cookie.to_str().unwrap_or(""); assert!( - !cookie_str.contains(COOKIE_SYNTHETIC_ID), - "Should not set duplicate synthetic_id cookie, got: {}", + cookie_str.contains(COOKIE_SYNTHETIC_ID), + "Should contain synthetic_id cookie, got: {}", cookie_str ); } diff --git a/crates/common/src/publisher.rs b/crates/common/src/publisher.rs index 7d8f92d..a096d34 100644 --- a/crates/common/src/publisher.rs +++ b/crates/common/src/publisher.rs @@ -5,8 +5,8 @@ use fastly::{Body, Request, Response}; use crate::backend::ensure_backend_from_url; use crate::http_util::{serve_static_with_etag, RequestInfo}; -use crate::constants::{COOKIE_SYNTHETIC_ID, HEADER_X_COMPRESS_HINT, HEADER_X_SYNTHETIC_ID}; -use crate::cookies::create_synthetic_cookie; +use crate::constants::{HEADER_X_COMPRESS_HINT, HEADER_X_SYNTHETIC_ID}; +use crate::cookies::set_synthetic_cookie; use crate::error::TrustedServerError; use crate::integrations::IntegrationRegistry; use crate::rsc_flight::RscFlightUrlRewriter; @@ -198,23 +198,8 @@ pub fn handle_publisher_request( // Generate synthetic identifiers before the request body is consumed. let synthetic_id = get_or_generate_synthetic_id(settings, &req)?; - let has_synthetic_cookie = req - .get_header(header::COOKIE) - .and_then(|h| h.to_str().ok()) - .map(|cookies| { - cookies.split(';').any(|cookie| { - cookie - .trim_start() - .starts_with(&format!("{}=", COOKIE_SYNTHETIC_ID)) - }) - }) - .unwrap_or(false); - log::debug!( - "Proxy synthetic IDs - trusted: {}, has_cookie: {}", - synthetic_id, - has_synthetic_cookie - ); + log::debug!("Proxy synthetic IDs - trusted: {}", synthetic_id,); let backend_name = ensure_backend_from_url(&settings.publisher.origin_url)?; let origin_host = settings.publisher.origin_host(); @@ -308,12 +293,7 @@ pub fn handle_publisher_request( } response.set_header(HEADER_X_SYNTHETIC_ID, synthetic_id.as_str()); - if !has_synthetic_cookie { - response.set_header( - header::SET_COOKIE, - create_synthetic_cookie(settings, synthetic_id.as_str()), - ); - } + set_synthetic_cookie(settings, &mut response, synthetic_id.as_str()); Ok(response) }