Update check: say what the forge answered, not zlib's "incorrect header check"
A Gitea that requires a sign-in does not refuse the branch archive: it redirects the download to its login page, which arrives as a 200 of HTML, and the admin page then reported zlib failing to unpack it — "incorrect header check". Both booths showed exactly that on 29 Sept once the sign-in requirement was switched on. The updater now names the case: "… requires a sign-in to read michael/ProdDash@main — turn off 'require sign-in to view' in Gitea, or make the repo readable without one". Any other answer that is not a gzip archive says what came back instead — a web page, or the content type — and where to look. tools/update-check.test.js drives the check against a mock forge: the login redirect, a bare HTML answer, an HTTP error, and a real archive that must still parse and be offered. Shell 1.9.3. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
92b98b6579
commit
601dc9e8b0
@@ -910,9 +910,21 @@ async function fetchArchive() {
|
||||
signal: AbortSignal.timeout(30000),
|
||||
headers: { 'User-Agent': `ProdDash/${SHELL_VERSION}` },
|
||||
});
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status} fetching ${REPO.owner}/${REPO.repo}@${REPO.branch}`);
|
||||
const where = `${REPO.owner}/${REPO.repo}@${REPO.branch}`;
|
||||
// A forge that wants a sign-in does not refuse: it redirects the download
|
||||
// to its login page, which arrives as a 200 of HTML. Say that, not
|
||||
// zlib's "incorrect header check".
|
||||
if (res.redirected && /\/user\/login\b|\/login\b/.test(new URL(res.url).pathname)) {
|
||||
throw new Error(`${FORGE.base} requires a sign-in to read ${where} — turn off "require sign-in to view" in Gitea, or make the repo readable without one`);
|
||||
}
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status} fetching ${where}`);
|
||||
const gz = Buffer.from(await res.arrayBuffer());
|
||||
if (gz.length > MAX_ARCHIVE_BYTES) throw new Error('archive is unexpectedly large');
|
||||
if (gz.length < 2 || gz[0] !== 0x1f || gz[1] !== 0x8b) {
|
||||
const type = String(res.headers.get('content-type') || 'unknown type').split(';')[0].trim();
|
||||
const looksHtml = /^\s*<(!doctype|html)/i.test(gz.subarray(0, 64).toString('utf8'));
|
||||
throw new Error(`${FORGE.base} answered with ${looksHtml ? 'a web page' : type} instead of the ${where} archive — check the forge address and that the repo is readable without a sign-in`);
|
||||
}
|
||||
const { files, comment } = parseTar(zlib.gunzipSync(gz));
|
||||
const stripped = new Map(); // drop the archive's single top-level folder
|
||||
for (const [p, data] of files) {
|
||||
|
||||
Reference in New Issue
Block a user