Skip to content

Make SSAT publisher HTML assembly truly streaming and parser-safe #857

Description

@ChristianPavilonis

Summary

Make the SSAT publisher HTML assembly path truly streaming and parser-safe.

The cache-control spec now defers origin-template caching and compression offload, but the architecture review found that the current publisher path still materializes origin bodies before client bytes can flow. This issue tracks the streaming/correctness work separately from the cache-header PR.

Problem

Current behavior has several streaming/correctness gaps:

  • Fastly publisher origin fetches can materialize the full origin response body in WASM heap before the client sees bytes.
  • EdgeZero/non-Fastly paths buffer the assembled publisher response.
  • The SSAT bid hold currently relies on a raw-byte </body search, which can false-positive inside inline scripts/JSON.
  • HTML post-processors can force full-document buffering, which undermines the intended SSAT streaming model.

These issues affect TTFB/FCP and make the SSAT assembly path more fragile, but they are broader than the initial cache-header policy work.

Proposed scope

  • Add/finish true publisher origin streaming with a cumulative response cap.
  • Ensure SSAT HTML can stream head/body while holding only the parser-confirmed body-close tail needed for bid injection.
  • Replace raw-byte </body detection with parser-context-aware close-body handling.
  • Review integrations/post-processors that force full-document buffering and either make them streaming-safe or explicitly route/document them as buffered mode.
  • Port or document equivalent behavior for EdgeZero/non-Fastly adapters.

Acceptance criteria

  • Fastly SSAT HTML path no longer requires full origin body materialization before sending client bytes.
  • Streaming path enforces a cumulative body cap without requiring a single full-body allocation.
  • Body-close hold is parser-context-aware and does not trigger on </body literals inside inline scripts/JSON.
  • EdgeZero/non-Fastly adapter behavior is either streaming-safe or explicitly documented/tested as buffered mode.
  • Tests cover large HTML, inline-script </body literals, missing body close tags, and normal bid injection.
  • Existing private, max-age=0 SSAT privacy behavior remains unchanged.

Out of scope

  • Origin-template caching.
  • Transformed-template caching.
  • Compression offload via Accept-Encoding: identity / X-Compress-Hint.
  • Auction backend timeout/name fixes.

Reference

See docs/superpowers/specs/2026-07-06-cache-control-header-design.md for the cache-control scope split and deferred follow-up list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    edgezeroEdgeZero migrationenhancementNew feature or requestrustPull requests that update rust code

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions