Internal callback server

The app/pdfrender/server package runs a second HTTP server, bound to 127.0.0.1 on a random port, that the browser talks to while rendering. It never faces the outside network.

Why it exists

The browser needs a URL to navigate to. Rather than write HTML to disk, the renderer stores the Document in an in-memory store keyed by a random document ID and hands the browser a URL on this internal server. The server then streams the document’s HTML and its assets to the browser.

Routes

RoutePurpose
GET /templates/:name/:document_idReturns the rendered body HTML the browser loads.
GET /templates/:name/:document_id/callbackThe page calls this to fire the callback lifecycle event.
GET /templates/:name/assets/*Serves the template’s assets/ to the browser.

The callback flow

When a template uses waitLifecycleEvent: callback, the renderer creates a callback channel stored alongside the document. The rendered page fetches the …/callback URL when ready; the handler signals the channel; the renderer unblocks and prints. See Lifecycle events.

Trace propagation

The internal server reconstructs the parent span from trace context passed as query parameters (or the Referer header), so browser-side requests join the same OpenTelemetry trace as the originating render.

Assets resolution

GetAsset looks up the template via the StoreConsumer (the LazyStore) and serves files from its assets provider. Path traversal outside a template’s assets/ directory is prevented.