diff --git a/crates/common/README.md b/crates/common/README.md index 4fa5fad2..35bb7850 100644 --- a/crates/common/README.md +++ b/crates/common/README.md @@ -33,9 +33,9 @@ Additional behavior: Helpers: -- `rewrite_creative_html(markup, settings) -> String` — rewrite an HTML fragment -- `rewrite_css_body(css, settings) -> String` — rewrite a CSS body (`url(...)` entries) -- `rewrite_srcset(srcset, settings) -> String` — proxy absolute candidates; preserve descriptors (`1x`, `1.5x`, `100w`) +- `rewrite_creative_html(settings, markup) -> String` — rewrite an HTML fragment +- `rewrite_css_body(settings, css) -> String` — rewrite a CSS body (`url(...)` entries) +- `rewrite_srcset(settings, srcset) -> String` — proxy absolute candidates; preserve descriptors (`1x`, `1.5x`, `100w`) - `split_srcset_candidates(srcset) -> Vec<&str>` — robust splitting for commas with/without spaces; avoids splitting the first `data:` mediatype comma Static bundles (served by publisher module): diff --git a/crates/common/src/creative.rs b/crates/common/src/creative.rs index 02041dd9..3036c805 100644 --- a/crates/common/src/creative.rs +++ b/crates/common/src/creative.rs @@ -22,16 +22,16 @@ //! `blob:`, `about:`. //! //! Notable helpers: -//! - `to_abs(&str) -> Option`: Normalizes a string to an absolute URL if +//! - `to_abs(&Settings, &str) -> Option`: Normalizes a string to an absolute URL if //! it is already absolute or protocol-relative; returns `None` otherwise or for //! non-network schemes. -//! - `rewrite_srcset(&str, &Settings) -> String`: Rewrites `srcset`/`imagesrcset` +//! - `rewrite_srcset(&Settings, &str) -> String`: Rewrites `srcset`/`imagesrcset` //! values, proxying absolute candidates and preserving descriptors (`1x`, //! `1.5x`, `100w`). //! - `split_srcset_candidates(&str) -> Vec<&str>`: Robust splitting that supports //! commas with or without spaces and avoids splitting the mediatype/data comma //! in a leading `data:` URL. -//! - `rewrite_css_body(&str, &Settings) -> String`: Rewrites url(...) occurrences +//! - `rewrite_css_body(&Settings, &str) -> String`: Rewrites url(...) occurrences //! inside CSS bodies. //! //! See the tests in this module for comprehensive cases, including irregular @@ -44,7 +44,7 @@ use lol_html::{element, html_content::ContentType, text, HtmlRewriter, Settings // Helper: normalize to absolute URL if http/https or protocol-relative. Otherwise None. // Checks against the rewrite blacklist to exclude configured domains/patterns from proxying. -pub(super) fn to_abs(u: &str, settings: &Settings) -> Option { +pub(super) fn to_abs(settings: &Settings, u: &str) -> Option { let t = u.trim(); if t.is_empty() { return None; @@ -77,7 +77,7 @@ pub(super) fn to_abs(u: &str, settings: &Settings) -> Option { } // Helper: rewrite url(...) occurrences inside a CSS style string to first-party proxy. -pub(super) fn rewrite_style_urls(style: &str, settings: &Settings) -> String { +pub(super) fn rewrite_style_urls(settings: &Settings, style: &str) -> String { // naive url(...) rewrite for absolute/protocol-relative URLs let lower = style.to_ascii_lowercase(); let mut out = String::with_capacity(style.len() + 16); @@ -114,7 +114,7 @@ pub(super) fn rewrite_style_urls(style: &str, settings: &Settings) -> String { (s, e) }; let url_val = &style[qs..qe]; - let new_val = if let Some(abs) = to_abs(url_val, settings) { + let new_val = if let Some(abs) = to_abs(settings, url_val) { build_proxy_url(settings, &abs) } else { url_val.to_string() @@ -204,7 +204,7 @@ pub(super) fn build_click_url(settings: &Settings, clear_url: &str) -> String { #[inline] pub(super) fn proxy_if_abs(settings: &Settings, val: &str) -> Option { - to_abs(val, settings).map(|abs| build_proxy_url(settings, &abs)) + to_abs(settings, val).map(|abs| build_proxy_url(settings, &abs)) } /// Split a srcset/imagesrcset attribute into candidate strings. @@ -257,7 +257,7 @@ pub(super) fn split_srcset_candidates(s: &str) -> Vec<&str> { /// - Proxies absolute or protocol-relative candidates via first-party endpoint /// - Preserves descriptors (e.g., `1x`, `1.5x`, `100w`) /// - Leaves relative candidates unchanged -pub(super) fn rewrite_srcset(srcset: &str, settings: &Settings) -> String { +pub(super) fn rewrite_srcset(settings: &Settings, srcset: &str) -> String { let mut out_items: Vec = Vec::new(); for item in split_srcset_candidates(srcset) { let it = item.trim(); @@ -267,7 +267,7 @@ pub(super) fn rewrite_srcset(srcset: &str, settings: &Settings) -> String { let mut parts = it.split_whitespace(); let url = parts.next().unwrap_or(""); let descriptor = parts.collect::>().join(" "); - let rewritten = if let Some(abs) = to_abs(url, settings) { + let rewritten = if let Some(abs) = to_abs(settings, url) { build_proxy_url(settings, &abs) } else { url.to_string() @@ -291,8 +291,8 @@ pub(super) fn proxied_attr_value(settings: &Settings, attr_val: Option) /// Rewrite a full CSS stylesheet body by normalizing url(...) references to the /// unified first-party proxy. Relative URLs are left unchanged. -pub fn rewrite_css_body(css: &str, settings: &Settings) -> String { - rewrite_style_urls(css, settings) +pub fn rewrite_css_body(settings: &Settings, css: &str) -> String { + rewrite_style_urls(settings, css) } /// Rewrite ad creative HTML to first-party endpoints. @@ -301,7 +301,7 @@ pub fn rewrite_css_body(css: &str, settings: &Settings) -> String { /// - `"#; - let out = rewrite_creative_html(html, &settings); + let out = rewrite_creative_html(&settings, html); let _expected = encode_url(&settings, "https://cdn.example/ad.html"); assert!(out.contains("/first-party/proxy?tsurl=")); let html2 = r#""#; - let out2 = rewrite_creative_html(html2, &settings); + let out2 = rewrite_creative_html(&settings, html2); assert!(out2.contains("/first-party/proxy?tsurl=")); let html3 = r#""#; - let out3 = rewrite_creative_html(html3, &settings); + let out3 = rewrite_creative_html(&settings, html3); assert!(out3.contains(" "#; - let out = rewrite_creative_html(html, &settings); + let out = rewrite_creative_html(&settings, html); assert!(!out.contains("/first-party/proxy?tsurl=")); assert!(out.contains("data:image/png;base64,AAAA")); assert!(out.contains("