/**
* Stream a file to an HTTP response without letting a mid-flight failure kill
* the daemon.
*
* `fs.createReadStream(p).pipe(res)` reads as safe when it sits inside a
* try/catch, but it is not: the catch only guards the SYNCHRONOUS setup. Once
* `.pipe()` returns, any later stream failure lands on a subsequent tick with
* no handler attached, and Bare terminates the process on an uncaught error.
*
* That is not a theoretical hazard. On celltron (2026-08-07) one click on a
* partially-synced repo took the whole forge down repeatedly:
*
* Uncaught StreamError: Writable stream closed
* at ReadableState.afterDestroy (streamx index.js:572)
* at FileReadStream._destroy (bare-fs index.js:2511)
* { code: 'PREMATURE_CLOSE' }
* [..] pear-git-v3 exited; restart in 60s
*
* Each death cost ~2.5 min of downtime — 60 s of supervisor backoff plus ~100 s
* remounting 36 repos before the HTTP port is bound again — so a user retrying
* the same link kept the forge in a self-sustaining crash loop.
*
* The usual trigger is NOT a corrupt file. It is the reader going away (a
* browser navigating off a large download, a client abort) or the file being
* rewritten underneath us by a concurrent sync. Both tear the pipe down and
* surface as PREMATURE_CLOSE. Serving one truncated response is the correct
* outcome; killing a daemon that hosts every other repo is not.
*/
/**
* Pipe `stream` into `res`, guaranteeing both ends are torn down exactly once
* and that no failure escapes as an uncaught error.
*
* Returns true so call sites can keep the `return pipeFile(...)` shape the
* router uses to signal "request handled".
*
* @param {object} stream a readable file stream (bare-fs / node fs)
* @param {object} res the HTTP response being written to
* @param {string} [label] what is being served, for the log line
*/
export function pipeFile (stream, res, label) {
let settled = false
const teardown = (err) => {
if (settled) return
settled = true
// A premature close is the expected shape of "reader hung up" — it is
// noise, not a fault. Anything else is worth a line in the log.
if (err && err.code !== 'PREMATURE_CLOSE') {
console.error('[web] stream failed' + (label ? ' for ' + label : '') + ': ' + (err.message || err))
}
try { stream.destroy() } catch {}
try { res.destroy() } catch {}
}
stream.on('error', teardown)
res.on('error', teardown)
// Normal completion also closes `res`; destroying an already-ended stream is
// a no-op, so this doubles as the "client vanished mid-body" cleanup without
// needing to tell the two cases apart.
res.on('close', () => {
if (settled) return
settled = true
try { stream.destroy() } catch {}
})
stream.pipe(res)
return true
}