feat: add pre-request header calculation - #709
Merged
Merged
Conversation
m2broth
marked this pull request as ready for review
August 25, 2026 13:41
m2broth
requested review from
b1ff,
blackrabbit99,
stas-nc,
wRLSS and
yehor-manzhula
and removed request for
wRLSS
August 25, 2026 13:41
stas-nc
reviewed
Aug 25, 2026
stas-nc
reviewed
Aug 25, 2026
stas-nc
reviewed
Aug 25, 2026
…dules PR feedback: the modules moved to TypeScript in this branch exported their single value as a default. Default exports let each importer choose its own name, so the same class or factory ends up called different things across the codebase, and they cannot be found by name in a search. Renamed exports: server-router.ts -> export class ServerRouter factory.ts -> export function tailorFactory request-fragment.ts -> export function requestFragmentFactory tailorx.ts -> export const Tailor Updated all importers: app.js, routes/wildcardRequestHandlerFactory.ts, types/PatchedHttpRequest.ts, tailor/factory.ts, and both tailor specs. The request-fragment spec keeps its local name via an import alias rather than renaming twenty call sites. No behaviour change. tailorx.ts was included because it is also new TypeScript in this branch and used a default export; its typed-seam contents are untouched. 636 passing, tsc clean, prettier clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Coverage ReportIlc/serverCommit SHA:72af0f9a8d74de07eb2cd8150ff25d407f4c51ef Test coverage results 🧪File details
Ilc/clientCommit SHA:72af0f9a8d74de07eb2cd8150ff25d407f4c51ef Test coverage results 🧪File details
RegistryCommit SHA:72af0f9a8d74de07eb2cd8150ff25d407f4c51ef Test coverage results 🧪File details
|
stas-nc
approved these changes
Aug 26, 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
ILC builds each fragment request by base64-encoding routerProps/appProps/sdk into the query string and forwarding inbound headers. Nothing checked the resulting size. When request line + headers exceeded a fragment's --max-http-header-size (Node's default 16384), the fragment answered 431 — and ILC only learned about it from that downstream failure, after every fragment on the page had already been dispatched and failed.
What this does
Measures the request line + header block before dispatch and, when over a configured ceiling, skips the request rather than sending it. The fragment resolves with an empty response instead of rejecting, so it degrades to a client-side render and produces one WARN, no ERROR — where previously each fragment logged an ERROR and called New Relic.
Measurement is exact, not estimated. serializeOutgoingRequest reproduces Node's _storeHeader from documented public API (getHeaders(), method, path, agent), and headFor prefers Node's own already-built _header for the two shapes reconstruction can't handle — a forwarded expect header, and headers passed as a flat array. A 35-test oracle in header-block.spec.ts compares the reconstruction against the bytes Node actually writes, byte-for-byte, across 19 request shapes.
maxFragmentRequestSize defaults to 0, which switches the guard off. Enable per deployment:
ILC_MAX_FRAGMENT_REQUEST_SIZE=15872