Fix truncated responses from compressed upstreams
build-container / build (push) Successful in 2m21s
build-container / build (push) Successful in 2m21s
fetch() decompresses transparently, but the proxies forwarded the upstream content-length, so browsers cut compressed Plex/Seafile responses short and JSON.parse failed. Ask Plex for identity encoding and drop the stale length whenever the upstream response was encoded. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4227883a29
commit
96fb6d807c
1 file changed
+5
-2
@@ -38,6 +38,7 @@ async function proxySeafile(req, res) {
|
||||
const out = {};
|
||||
for (const h of ['content-type', 'content-length', 'content-disposition', 'content-range', 'accept-ranges']) {
|
||||
if (inline && h === 'content-disposition') continue;
|
||||
if (h === 'content-length' && upstream.headers.get('content-encoding')) continue; // decompressed by fetch, so the length changed
|
||||
const v = upstream.headers.get(h);
|
||||
if (v) out[h] = v;
|
||||
}
|
||||
@@ -245,14 +246,16 @@ async function plexApi(req, res) {
|
||||
async function plexProxy(req, res) {
|
||||
const ck = parseCookies(req), base = unsigned(ck.plex_srv), tok = ck.plex_stk;
|
||||
if (!base || !tok) { res.writeHead(401); return res.end(); }
|
||||
const headers = { ...PLEX_HEADERS, 'X-Plex-Token': tok, Accept: req.headers.accept || 'application/json' };
|
||||
const headers = { ...PLEX_HEADERS, 'X-Plex-Token': tok, Accept: req.headers.accept || 'application/json', 'Accept-Encoding': 'identity' };
|
||||
if (req.headers.range) headers.range = req.headers.range;
|
||||
const ac = new AbortController();
|
||||
res.on('close', () => ac.abort());
|
||||
try {
|
||||
const up = await fetch(base + req.url.slice('/plex'.length), { headers, signal: ac.signal });
|
||||
const out = {};
|
||||
for (const h of ['content-type', 'content-length', 'content-range', 'accept-ranges']) { const v = up.headers.get(h); if (v) out[h] = v; }
|
||||
// fetch() transparently decompresses, so an upstream content-length would no longer match the bytes we send.
|
||||
const encoded = !!up.headers.get('content-encoding');
|
||||
for (const h of ['content-type', 'content-length', 'content-range', 'accept-ranges']) { if (encoded && h === 'content-length') continue; const v = up.headers.get(h); if (v) out[h] = v; }
|
||||
if (req.url.startsWith('/plex/photo/')) out['cache-control'] = 'private, max-age=86400';
|
||||
res.writeHead(up.status, out);
|
||||
if (up.body) Readable.fromWeb(up.body).on('error', () => res.destroy()).pipe(res); else res.end();
|
||||
|
||||
Reference in new issue
Block a user