Table of Contents

Class BundleManifest

Namespace
CobaltPdf.WebKit.Infrastructure.Provisioning
Assembly
CobaltPDF.WebKit.dll

Per-RID source-of-truth for which bundle to fetch and what SHA-256 it must have. The values here are pinned to the package version — every release publishes fresh bundles and updates this table.

To override at deployment time, set COBALT_BUNDLE_URL (and optionally COBALT_BUNDLE_SHA256) — see BundleProvisioner.

public static class BundleManifest
Inheritance
BundleManifest
Inherited Members

Fields

BundleVersion

Bundle release version. Bumped on every WebKit upgrade or build-recipe change so cached extractions are invalidated cleanly. The cache path embeds this version (cobalt-webkit-bundle-{rid}-v{BundleVersion}/) so installing a NuGet that bumps it side-steps the previous extraction entirely rather than overwriting in place.

History: 0.2.0 — Ubuntu 22.04 base (glibc 2.35), libwebkit2gtk-4.1, py3.10. 0.3.0 — Ubuntu 24.04 base (glibc 2.39), libwebkit2gtk-4.1, py3.12. Bundle layout unchanged; only the binaries inside it move. 0.3.1 — render.py: trial watermark is now a non-editable PIL raster (tiled transparent PNG composited per page) instead of selectable text, drawn in bundled Liberation Sans Bold (the body-text metric clone — deterministic, never a serif). Bundle-content change → cache-busting bump. Re-spun 2026-06-07: WithFonts(dir) now applies in pooled --serve mode (was a no-op outside one-shot --json) plus the viewport-override honor fix, LP_NUM_THREADS=1, and a smaller default desktop viewport. The compiled render.so carries all of these. SHAs below updated accordingly. Re-spun again: hardened the GTK print path against the cold-start "Printer not found" race — the file backend registers its printer asynchronously, so the first render after a fresh extract could lose the race and (worse) hang because a synchronous failure was driven into Gtk.main(). Now pre-warms + retries (pumping the loop) and never enters the loop once the op has settled. SHAs below updated again. Re-spun once more: dropped the build-only static Python archives (libpython3.12.a/-pic.a, ~27 MB extracted / ~7 MB in the tarball) — the embedded interpreter is statically linked and never loads them at runtime. SHAs below updated again. 1.0.0 — First PUBLISHED bundle baseline (the 0.x numbers above were internal dev iterations). Carries the cold-start reliability fix in launch.sh: Xvfb now claims its display atomically via -displayfd instead of a racy /tmp/.X(N)-lock scan, so multiple workers starting concurrently can't collide on one display and wedge — plus a startup check that aborts the worker cleanly if Xvfb fails (the pool then respawns). From here, bump this ONLY when the bundle payload (WebKit/fonts/render engine) changes — it is independent of the NuGet package version. 1.0.1 — Cookie-delivery fix in the render engine: cookies added via AddCookie(name, value) with no explicit domain are now applied through document.cookie + reload against the final post-redirect host, so they reach public REGISTRABLE domains. The previous cookie_mgr.add_cookie path silently dropped such cookies on the ephemeral WebsiteDataManager (they survived only for IP / intranet hosts). render.py source unchanged in behaviour for explicit-domain and IP cookies; only the recompiled render.so moves. SHAs below updated accordingly. 1.0.2 — NO-RELOAD cookies + lazy-load parity + WSL GL fix: • Cookies are now committed to the jar BEFORE navigation (registrable domain inferred from the target URL, Chromium's eTLD+1 table) AND re-asserted via a document-start user-script in every document — including the page reached after a client-side redirect (bbc.com → bbc.co.uk) — so a consent banner is dismissed with NO page reload. Replaces the 1.0.1 document.cookie+reload path (which was slow and raced lazy-load). • Lazy-load re-ported verbatim from the Chromium edition's LazyLoadScroll.js (half-page steps up to pageCount paper-heights; completion polled from Python since this WebKit's evaluate_javascript does not await Promises). • launch.sh stages the Mesa DRI drivers on tmpfs + pre-faults GL libs to dodge the intermittent WSL2 swrast mmap EFAULT — GATED to WSL only (skipped on native Linux / Azure / containers where it is unneeded and would starve a small /dev/shm); opt-out COBALT_WSL_GL_FIX=0. SHAs below updated accordingly.

public const string BundleVersion = "1.0.2"

Field Value

string

DefaultBaseUrl

Base URL bundles are published under. Override at runtime with BundleBaseUrl or the COBALT_BUNDLE_BASE_URL env var when self-hosting (e.g. an air-gapped Artifactory).

The canonical layout is: {base}/v{BundleVersion}/cobalt-webkit-bundle-{rid}.tar.gz

public const string DefaultBaseUrl = "https://github.com/CobaltPDF/cobalt-webkit-bundles/releases/download"

Field Value

string

Remarks

Points at the public GitHub Releases for the bundle repo. Assets are served anonymously (the repo is public) and the canonical layout maps onto GitHub's /releases/download/{tag}/{asset} scheme: the v{BundleVersion} path segment is the release tag and the cobalt-webkit-bundle-{rid}-{variant}.tar.gz segment is the asset name. Override with BundleBaseUrl or COBALT_BUNDLE_BASE_URL for a private feed / air-gapped mirror.

Methods

PublishedRuntimes()

Returns the RIDs that currently have at least one published variant.

public static IReadOnlyCollection<string> PublishedRuntimes()

Returns

IReadOnlyCollection<string>

Resolve(string, Version?, string?, string?)

Resolve a BundleSource for runtimeId, selecting the variant that matches hostGlibc. baseUrlOverride wins over the default base URL when non-null. sha256Override wins over the manifest hash when non-null — useful for self-hosted bundles whose SHA differs.

public static BundleSource Resolve(string runtimeId, Version? hostGlibc = null, string? baseUrlOverride = null, string? sha256Override = null)

Parameters

runtimeId string
hostGlibc Version
baseUrlOverride string
sha256Override string

Returns

BundleSource

SelectVariant(string, Version?)

Choose the best bundle variant for runtimeId given the host's glibc. Picks the NEWEST published variant whose floor the host satisfies. When hostGlibc is null (unknown) the most-compatible (lowest-floor) variant is chosen so the render still has the best chance of working. Throws a clear, actionable error when the host's glibc is older than every available variant.

public static BundleVariant SelectVariant(string runtimeId, Version? hostGlibc)

Parameters

runtimeId string
hostGlibc Version

Returns

BundleVariant

VariantIdForGlibc(string, Version?)

Stable variant id used for the cache/extraction path, chosen by host glibc across ALL declared variants (never throws, ignores publish state). Computed before the publish/SHA check so the warm-start fast-path and pre-staged bundles work without resolving a source.

public static string VariantIdForGlibc(string runtimeId, Version? hostGlibc)

Parameters

runtimeId string
hostGlibc Version

Returns

string