Add configuration options for Dynamic Content Assembly (DCA) defaults#52
Merged
Conversation
Add Configuration.default_dca field that controls how <esi:include> and <esi:eval> tags without an explicit dca attribute are processed. - Change IncludeAttributes.dca to Option<DcaMode> to distinguish 'not specified' (None) from explicit 'dca=none' (Some(None)) - Add with_default_dca() builder method on Configuration - Re-export DcaMode publicly for use in config API - Resolve effective DCA at evaluation time: explicit tag attr > Configuration.default_dca Addresses #46
Add a safety limit on recursive ESI include/eval nesting depth (default: 15, per EdgeSuite ESI spec). When the limit is reached, fragments are silently omitted from output and a warning is logged — matching Akamai behaviour. - Add max_include_depth field to Configuration (default: 15) - Add with_max_include_depth() builder method - Track include_depth in Processor, increment for nested processing - Enforce limit in process_fragment_body (include dca=esi) and on_eval (both dca=esi two-phase and dca=none single-phase paths) - Log warn! when depth limit is exceeded Addresses #46
When `enable_edge_control` is true, inspect the `Edge-Control` response header on fragment responses for `dca=esi` or `dca=noop` directives. This provides per-fragment control of ESI processing via origin response headers, matching Akamai's 'Enable Through Response Headers' property setting. NOTE: No other Edge-Control header directives are supported at this time - Add `enable_edge_control` config option (default: `false`) - Change `FragmentMetadata.dca` to `Option<DcaMode>` to defer resolution - Add `Processor::resolve_dca()` applying precedence: `ESI tag attribute > Edge-Control header > Configuration.default_dca` - Add parse_edge_control_dca() per EdgeSuite ESI spec: `dca=esi` (process as ESI) and `dca=noop` (do not process) - Wire into `process_include()` and `on_eval()` response paths Addresses #46
When enabled, an unspecified <esi:include> inside an explicit dca=esi subtree resolves to Esi processing instead of falling back to the global default_dca. Allows users to set default_dca=None globally while still having dca=esi propagate to its children's subtree. Precedence: tag attr > Edge-Control > inherited (if enabled & depth>0) > default_dca.
Cover all four DCA features: default_dca, max_include_depth, Edge-Control header parsing, and inherit_parent_dca subtree inheritance. 24 tests verifying precedence rules, edge cases, and feature interactions.
Demonstrates all four DCA config options: default_dca, edge_control, inherit_parent_dca, and max_include_depth.
kailan
previously approved these changes
May 28, 2026
Member
kailan
left a comment
There was a problem hiding this comment.
This looks really good. Thanks for the well-defined commits!
Co-authored-by: Kailan Blanks <kblanks@fastly.com>
kailan
approved these changes
May 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
There is currently no way to control the default DCA (Dynamic Content Assembly) behaviour for
<esi:include>and<esi:eval>tags — either globally across all fragments, or on a per-fragment basis via response headers. Users who want Akamai-style "ESI-by-default" processing must adddca="esi"to every tag. There is also no depth limit enforcement, noEdge-Controlheader support, and no way for child fragments to inherit a parent's DCA mode.Fixes #46
Changes
Adds four new configuration options to
Configuration:default_dca(DcaMode, default:None) — Sets the global default DCA mode for includes/evals without an explicitdcaattribute. Set toDcaMode::Esito enable Akamai-style behaviour where all fragments are ESI-processed by default.max_include_depth(usize, default:15) — Enforces a maximum nesting depth for ESI includes/evals. The EdgeSuite spec defaults to 15 levels. When the limit is reached, fragment content is silently omitted.enable_edge_control(bool, default:false) — Enables parsing ofEdge-Controlresponse headers for per-fragment DCA directives (e.g.Edge-Control: dca=esi). Matches Akamai's "Enable Through Response Headers" property setting.inherit_parent_dca(bool, default:false) — When enabled, child fragments inside an explicitdca="esi"subtree inherit ESI processing without needing their own attribute. Top-level includes still usedefault_dca.Precedence (highest wins): tag attribute → Edge-Control header → inherited parent DCA →
default_dca.Also makes
DcaModea public export and changes the internaldcafield fromDcaModetoOption<DcaMode>to distinguish "not specified" from "explicitly set to none".Usage
Tests
Comprehensive test suite in
dca_tests.rscovering all four features (23 tests total), including precedence interactions between config, tag attributes, Edge-Control headers, and inheritance.Example
New
esi_dca_exampledemonstrating all four DCA configuration options.