jm-tech-power-official/Flash Download
A desktop download manager that opens up to 32 connections against one file and can send each of them out a different proxy route.
Public
Uncategorized
Clone
jm-tech-power-official/flash-download.jmproj
test/fixture-server.js
// Local origin + two proxies, so the running app exercises real range requests
// and real proxy routing. Bytes are generated, never stored.
const http = require('http');
const { URL } = require('url');
// Real servers do not hand every connection the same throughput. Every third
// connection here gets a quarter of the rate, so lanes finish unevenly and the
// tail behaviour is actually exercised.
let conns = 0;
const rateFor = (kbps) => { conns += 1; return conns % 3 === 0 ? Math.round(kbps / 4) : kbps; };
const FILES = {
'/ubuntu-24.04.3-live-server-amd64.iso': { size: 320 * 1024 * 1024, kbps: 900 },
'/imagenet-val-2012.tar': { size: 180 * 1024 * 1024, kbps: 420 },
'/blender-4.2.1-linux-x64.tar.xz': { size: 26 * 1024 * 1024, kbps: 2400 },
'/tiny': { size: 1024, kbps: 0 },
};
const chunkOf = (() => { const b = Buffer.alloc(64 * 1024); for (let i = 0; i < b.length; i++) b[i] = (i * 2654435761) & 0xff; return b; })();
const origin = http.createServer((req, res) => {
const path = new URL(req.url, 'http://x').pathname;
const file = FILES[path];
if (!file) { res.writeHead(404); return res.end(); }
let start = 0, end = file.size - 1, status = 200;
const m = /bytes=(\d+)-(\d*)/.exec(req.headers.range || '');
if (m) { start = +m[1]; end = m[2] ? +m[2] : file.size - 1; status = 206; }
end = Math.min(end, file.size - 1);
const len = end - start + 1;
const headers = { 'content-length': String(len), 'accept-ranges': 'bytes', etag: '"fixture-v1"', 'content-type': 'application/octet-stream' };
if (status === 206) headers['content-range'] = `bytes ${start}-${end}/${file.size}`;
res.writeHead(status, headers);
if (!len) return res.end();
if (!file.kbps) return res.end(chunkOf.subarray(0, len));
let sent = 0;
const per = Math.max(4096, Math.round((rateFor(file.kbps) * 1024) / 10));
const tick = () => {
if (res.writableEnded || !res.socket || res.socket.destroyed) return;
const n = Math.min(per, len - sent);
res.write(chunkOf.subarray(0, Math.min(n, chunkOf.length)));
sent += Math.min(n, chunkOf.length);
if (sent >= len) return res.end();
setTimeout(tick, 100);
};
tick();
});
function proxy(name) {
return http.createServer((req, res) => {
let target;
try { target = new URL(req.url); } catch { res.writeHead(400); return res.end(); }
const up = http.request({ host: target.hostname, port: target.port || 80, path: target.pathname + target.search, method: req.method, headers: req.headers },
(pr) => { res.writeHead(pr.statusCode, pr.headers); pr.pipe(res); });
up.on('error', () => { try { res.writeHead(502); res.end(); } catch {} });
req.pipe(up);
});
}
const a = proxy('a'), b = proxy('b');
origin.listen(18080, '127.0.0.1');
a.listen(18081, '127.0.0.1');
b.listen(18082, '127.0.0.1');
console.log('fixture up: origin 18080, proxies 18081/18082');