mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
Let uploaders declare a backup origin at creation time so the swarm can keep streaming when the primary CDN is overloaded. - upload-modal.html: the single "Web Seed (ws)" input becomes a "Web seeds (one per line)" textarea with help text explaining the backup-origin use case and the byte-identical-file requirement. - UploadModal: in upload mode the R2/CDN url stays the primary webseed and any textarea entries follow it (passed as [primaryUrl, textarea]); external mode already flowed the field through. All parsing stays in the payload layer. - videoNotePayload.normalizeWebSeedList now splits every entry (array OR string) on newlines/commas, so the upload-modal's [url, "a\nb"] shape and a plain multi-line string both expand + dedupe correctly. Mutation-verified (array entries no longer split fails the upload-shape test); build + full unit suite green. Lints relevant to the change (inline-styles, tokens, innerHTML) pass. Note: npm run lint also reports pre-existing file-size violations in unrelated files (SignerManager, watchHistory, playbackService, webtorrent, etc.) that grew in earlier commits — none are touched here. Flagging separately. Co-Authored-By: Claude Opus 4.8 <[email protected]>
117 lines
4.2 KiB
JavaScript
117 lines
4.2 KiB
JavaScript
// A video may legitimately declare more than one web seed (e.g. the primary CDN
|
|
// plus an independent backup origin) so the WebTorrent swarm can pull pieces
|
|
// from either when one is overloaded. Multiple `ws=` params are the standard
|
|
// BEP19 carrier and playback already attaches every one of them, so the
|
|
// authoring/normalization layer must preserve the full set — never collapse it
|
|
// to a single seed.
|
|
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { extractAllWebSeeds } from "../js/magnetShared.js";
|
|
import { normalizeVideoNotePayload } from "../js/services/videoNotePayload.js";
|
|
|
|
const BTIH = "a".repeat(40);
|
|
const MAGNET = `magnet:?xt=urn:btih:${BTIH}`;
|
|
const SEED_A = "https://cdn-a.example.com/video.mp4";
|
|
const SEED_B = "https://cdn-b.example.com/video.mp4";
|
|
|
|
test("extractAllWebSeeds returns every ws= in order, deduped", () => {
|
|
const magnet = `${MAGNET}&ws=${encodeURIComponent(SEED_A)}&ws=${encodeURIComponent(
|
|
SEED_B,
|
|
)}&ws=${encodeURIComponent(SEED_A)}`;
|
|
assert.deepEqual(extractAllWebSeeds(magnet), [SEED_A, SEED_B]);
|
|
});
|
|
|
|
test("extractAllWebSeeds returns [] when there are no web seeds", () => {
|
|
assert.deepEqual(extractAllWebSeeds(MAGNET), []);
|
|
assert.deepEqual(extractAllWebSeeds(""), []);
|
|
assert.deepEqual(extractAllWebSeeds(null), []);
|
|
});
|
|
|
|
test("an array of web seeds all survive into the published magnet", () => {
|
|
const { payload, errors } = normalizeVideoNotePayload({
|
|
title: "Multi seed",
|
|
magnet: MAGNET,
|
|
ws: [SEED_A, SEED_B],
|
|
});
|
|
|
|
assert.deepEqual(errors, []);
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.ok(seeds.includes(SEED_A), "first webseed must be carried in the magnet");
|
|
assert.ok(seeds.includes(SEED_B), "second webseed must be carried in the magnet");
|
|
});
|
|
|
|
test("a newline/comma-delimited ws field is split into multiple seeds", () => {
|
|
const { payload } = normalizeVideoNotePayload({
|
|
title: "Multi seed text",
|
|
magnet: MAGNET,
|
|
ws: `${SEED_A}\n${SEED_B}`,
|
|
});
|
|
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.ok(seeds.includes(SEED_A));
|
|
assert.ok(seeds.includes(SEED_B));
|
|
});
|
|
|
|
test("the hosted CDN url is added as a webseed alongside the explicit ones", () => {
|
|
const cdn = "https://cdn.example.com/video.mp4";
|
|
const { payload } = normalizeVideoNotePayload({
|
|
title: "Cdn plus seed",
|
|
url: cdn,
|
|
magnet: MAGNET,
|
|
ws: SEED_A,
|
|
});
|
|
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.ok(seeds.includes(SEED_A), "explicit webseed preserved");
|
|
assert.ok(seeds.includes(cdn), "hosted url also attached as a webseed");
|
|
});
|
|
|
|
test("a single webseed string still works (back-compat)", () => {
|
|
const { payload } = normalizeVideoNotePayload({
|
|
title: "Single seed",
|
|
magnet: MAGNET,
|
|
ws: SEED_A,
|
|
});
|
|
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.deepEqual(seeds, [SEED_A]);
|
|
// The single content `ws` field still reflects the primary seed.
|
|
assert.equal(payload.legacyFormData.ws, SEED_A);
|
|
});
|
|
|
|
test("upload-modal shape ([primaryUrl, textarea]) yields primary-first, all split", () => {
|
|
// This mirrors exactly what UploadModal hands over in upload mode: the CDN
|
|
// url as the primary entry, followed by the raw multi-line textarea value.
|
|
const cdn = "https://cdn.example.com/video.mp4";
|
|
const { payload } = normalizeVideoNotePayload({
|
|
title: "Upload shape",
|
|
url: cdn,
|
|
magnet: MAGNET,
|
|
ws: [cdn, `${SEED_A}\n${SEED_B}`],
|
|
});
|
|
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.ok(seeds.includes(cdn), "CDN url carried");
|
|
assert.ok(seeds.includes(SEED_A), "first backup webseed carried");
|
|
assert.ok(seeds.includes(SEED_B), "second backup webseed carried");
|
|
// CDN stays the primary (first) seed.
|
|
assert.equal(payload.legacyFormData.ws, cdn);
|
|
});
|
|
|
|
test("duplicate webseeds are not written twice", () => {
|
|
const { payload } = normalizeVideoNotePayload({
|
|
title: "Dupe seed",
|
|
magnet: MAGNET,
|
|
ws: [SEED_A, SEED_A, " " + SEED_A + " "],
|
|
});
|
|
|
|
const seeds = extractAllWebSeeds(payload.legacyFormData.magnet);
|
|
assert.equal(
|
|
seeds.filter((s) => s === SEED_A).length,
|
|
1,
|
|
"the same webseed must appear at most once",
|
|
);
|
|
});
|