From 83b2cd193fcbb3341084b7d01977d9938af03fe1 Mon Sep 17 00:00:00 2001 From: Mateus Date: Wed, 22 Apr 2026 14:07:02 -0300 Subject: [PATCH] docs: Add README.md file for the ad_insertion plugin --- plugins/samples/ad_insertion/README.md | 98 ++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 plugins/samples/ad_insertion/README.md diff --git a/plugins/samples/ad_insertion/README.md b/plugins/samples/ad_insertion/README.md new file mode 100644 index 00000000..3e0a3f79 --- /dev/null +++ b/plugins/samples/ad_insertion/README.md @@ -0,0 +1,98 @@ +# Ad Insertion Plugin + +This plugin modifies HTTP response bodies to dynamically insert Google Ad Manager (GAM) ad units into HTML content. It operates during the **response body** processing phase by buffering the full HTML body and injecting the `gpt.js` library along with specific ad containers based on configuration markers. It reads ad placements from a configuration payload during **plugin initialization** and prevents infinite loops by avoiding ad insertion on requests for ad scripts themselves. Use this plugin when you need to centrally inject and manage ad placeholders across backend services without modifying their application code. + +## Implementation Notes + +- **Configuration parsing**: Loads a CSV-like text configuration at module initialization to define the GPT library URL and various ad slot configurations (slot path, size, relative marker, and placement). +- **Infinite loop prevention**: Inspects the `:path` header to identify and skip ad requests (e.g., `/ads/`) to avoid injecting ads into ad script responses. +- **Content type matching**: Checks the `Content-Type` response header to ensure manipulation only occurs on `text/html` payloads. +- **Body buffering**: Returns `StopIterationAndBuffer` until the end of the stream to ensure the entire HTML document is available, avoiding issues with split HTML tags across chunks. +- **Content-Length removal**: Safely removes the `Content-Length` response header because the overall size of the body increases upon ad insertion. +- **Single pass insertion**: Matches HTML markers and prepares all insertions, applying them from bottom to top to preserve accurate string positions. + +## Configuration Parsing + +All implementations parse a CSV-like text format: + +- **C++**: + ```cpp + for (absl::string_view line : absl::StrSplit(config_str, '\n')) { + absl::string_view stripped = absl::StripAsciiWhitespace(line); + if (stripped.empty() || stripped[0] == '#') continue; + + std::vector parts = absl::StrSplit(stripped, ','); + // Processes directives based on parts[0]... + } + ``` + Uses Abseil for string splitting and trims whitespace to populate ad configurations. + +- **Rust**: + Uses Rust's iterator-based string processing and `split(',')` to parse the same payload format into custom configuration structures. + +### Configuration Format + +The plugin requires a configuration file with comma-separated values. + +**Example configuration** (`tests.config`): +``` +gpt_url, https://custom.pubads.g.doubleclick.net/tag/js/gpt.js +inject_gpt, true +ad, custom_header, /9999/custom_header_ad, 970x250, true,
+ad, custom_footer, /9999/custom_footer_ad, 728x90, false,