Skip to content

Forward CouchDB custom headers to fast fetch requests - #82

Open
nimula wants to merge 1 commit into
vrtmrz:mainfrom
nimula:fix/fast-fetch-custom-headers
Open

Forward CouchDB custom headers to fast fetch requests#82
nimula wants to merge 1 commit into
vrtmrz:mainfrom
nimula:fix/fast-fetch-custom-headers

Conversation

@nimula

@nimula nimula commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Forward the configured CouchDB custom headers to Fast Fetch's native fetch requests.

Context

Fast Fetch (fetchChangesForInitialSync in StreamingFetch.ts, called from Rebuilder.ts) builds its own request headers from scratch and never reads couchDB_CustomHeaders. This is inconsistent with the normal replication path, which parses couchDB_CustomHeaders with parseHeaderValues() and merges it into every PouchDB HTTP request via the fetch override in RemoteService.ts.

Behind a reverse proxy that requires custom headers (for example, Cloudflare Access Service Auth with CF-Access-Client-Id / CF-Access-Client-Secret), this means normal replication and the initial configuration checks succeed, but every Fast Fetch request is rejected by the proxy. The two request stages that were not checking response.ok compounded the symptom: an HTML/JSON error page from the proxy was parsed as if it were changes-feed data, so the failure surfaced only as a generic retry loop with no HTTP status information.

Related, but not the same issue:

Changes

  • src/pouchdb/StreamingFetch.ts
    • Add an optional trailing customHeaders?: Record<string, string> parameter to fetchChangesForInitialSync.
    • Merge customHeaders into the request headers, assigning Authorization last so custom headers cannot override the CouchDB credential.
    • Add a throwIfNotOk() helper and call it before consuming the changes-summary and changes-stream responses, so a non-2xx response (401/403/etc.) raises a clear error naming the request stage and HTTP status instead of being parsed as JSON. The message intentionally omits header values.
    • Keep the database-info request tolerant of failure (as before), logging the status at verbose level instead of throwing, since the target sequence is recovered from the changes summary anyway.
  • src/serviceModules/Rebuilder.ts
    • Parse settings.couchDB_CustomHeaders with the existing parseHeaderValues() helper and pass it through to fetchChangesForInitialSync.
    • Log the caught exception at verbose level on each retry, so the underlying HTTP status is visible instead of only "Fast fetch interrupted. Retrying from sequence: N".

Verification

Ran from this package (livesync-commonlib) directly:

  • npm run check:types — clean, no errors.
  • npm test — 65 files / 1210 tests passed.

Ran from the top-level plug-in repository (obsidian-livesync) against the two changed files:

  • npx vitest run --config vitest.config.unit.ts src/lib/src/pouchdb/StreamingFetch.unit.spec.ts src/lib/src/serviceModules/Rebuilder.unit.spec.ts — 25/25 passed, including 6 new cases covering header forwarding, Authorization precedence, and the response.ok diagnostics.
  • npx eslint src/lib/src/pouchdb/StreamingFetch.ts src/lib/src/serviceModules/Rebuilder.ts — 0 errors.

Note: the top-level plug-in repository's own tsc --noEmit and npm run build are currently failing against this branch for reasons unrelated to this change — the plug-in repository's src/lib pin is ~40 commits behind this package's main, and this package's main has already removed the global eventHub export and other APIs the plug-in repository has not yet migrated to. That gap is pre-existing and reproduces identically on a clean checkout of main with this branch's four files stashed out, so it is not caused by this change.

Fast Fetch built its own fetch headers from scratch and never read
couchDB_CustomHeaders, unlike the normal replication path. Behind a
reverse proxy that requires custom headers (e.g. Cloudflare Access
Service Auth), this silently dropped every Fast Fetch request while
normal replication kept working, and the resulting 401/403 responses
were parsed as if they were changes-feed JSON.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant