readest/apps/readest-app/.claude/memory/opds-preemptive-basic-digest-400.md
Huang Xin 883dae36aa
fix(opds): auth negotiation and auto-download fixes for self-hosted catalogs (#5002)
* fix(opds): allow LAN catalogs through the proxy in development

The SSRF host blocklist added in #4638 unconditionally rejected private
addresses, so the dev proxy returned 400 for LAN OPDS catalogs even though
next dev runs on the developer's own machine where reaching the LAN is the
normal use case. Skip the blocklist when NODE_ENV is development, matching
the existing CatalogManager gate that only forbids LAN URLs in production.
Production and test behavior are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(opds): negotiate Digest auth when the server rejects preemptive Basic with 400

Calibre's content server in digest mode, or auto mode over http, answers a
Basic Authorization header with 400 Unsupported authentication method
instead of a 401 challenge. The preemptive Basic header introduced in #4206
therefore dead-ended the request, since the auth retry only fired on 401 or
403, and digest catalogs failed with Failed to load OPDS feed: 400 Bad
Request on every platform. When a request that carried preemptive Basic
comes back 400, re-issue it once without credentials to surface the
WWW-Authenticate challenge and let the existing negotiation pick the scheme
the server actually wants. Verified end to end against a live Calibre
server on web and Android.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(opds): skip SSL verification in auto-download like the manual download path

The native download_file command validates TLS with rustls, which ignores
the OS trust store, so downloads from self-signed or private-CA OPDS
servers fail in the TLS handshake before any request reaches the server.
The manual download path has passed skipSslVerification since #2900 as the
workaround for #2871, but the auto-download path never did, so subscribed
shelves failed to sync while feed browsing and manual downloads of the same
books worked. Pass the same flag in downloadAndImport.

Closes #4988

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 19:47:26 +02:00

2 KiB

name description metadata
opds-preemptive-basic-digest-400 Calibre digest/'auto' servers 400 the preemptive Basic header from PR #4206; fetchWithAuth must bare-retry on 400 to surface the Digest challenge
node_type type originSessionId
memory project 9066b80b-3cb5-44df-9c4b-7f609cf285a5

Calibre's content server in digest (or auto over http) auth mode responds to a Basic Authorization header with 400 "Unsupported authentication method" — not a 401 challenge. PR #4206 (commit 83607d14e) made fetchWithAuth (src/app/opds/utils/opdsReq.ts) send Basic preemptively (for Calibre-Web-style servers that return anonymous 200 without a challenge), which dead-ended all digest-mode Calibre servers: the retry logic only fired on 401/403, so users saw "Failed to load OPDS feed: 400 Bad Request" (reported on Android, but platform-independent — web proxy relays the 400 too).

Fix (2026-07-08): in fetchWithAuth, when the first response is 400 AND preemptive Basic was sent, re-issue the request once without credentials to surface WWW-Authenticate, then let the existing 401/403 negotiation pick Digest. Direct path strips the Authorization header; proxy path strips the auth= query param. Tests in src/__tests__/utils/opds-req.test.ts.

Why: the two auth-server archetypes conflict — anonymous-200 servers need preemptive creds (#4206), strict digest servers reject them with 400. Only runtime negotiation satisfies both; don't "fix" one archetype by regressing the other.

How to apply: any preemptive-auth optimization needs a recovery path for servers that reject the scheme outright (400/4xx without challenge), not just for 401/403 challenges. The app's Digest implementation itself is correct (Calibre's strict parser answers 401, not 400, to its headers). Verify against a real Calibre: dummy creds distinguish malformed (400) from wrong-password (401). Beware: Calibre throttles repeated failed logins with transient 503s. Related: security-advisories-web-2026-06 (the other OPDS 400 — dev-LAN SSRF block in the proxy).