feat(torrents): add tracker timing controls

This commit is contained in:
NimBold
2026-08-02 10:24:59 +03:30
parent 1d27b5b0bf
commit 48b4d984a2
19 changed files with 516 additions and 11 deletions
+19
View File
@@ -10,6 +10,8 @@ import {
isValidTorrentTrackerList,
normalizeTorrentEncryptionPolicy,
normalizeTorrentPrioritizePiece,
normalizeTorrentTrackerInterval,
normalizeTorrentTrackerTimeout,
redactDownloadForPersistence,
resolveDownloadConnections
} from './downloads';
@@ -107,6 +109,23 @@ describe('Torrent encryption policy validation', () => {
});
});
describe('Torrent tracker timing validation', () => {
it('accepts bounded timeout values and an automatic interval', () => {
expect(normalizeTorrentTrackerTimeout('1')).toBe(1);
expect(normalizeTorrentTrackerTimeout(604800)).toBe(604800);
expect(normalizeTorrentTrackerInterval('0')).toBe(0);
expect(normalizeTorrentTrackerInterval(604800)).toBe(604800);
});
it('rejects zero timeouts and out-of-range timing values', () => {
expect(normalizeTorrentTrackerTimeout('0')).toBeUndefined();
expect(normalizeTorrentTrackerTimeout(604801)).toBeUndefined();
expect(normalizeTorrentTrackerInterval(-1)).toBeUndefined();
expect(normalizeTorrentTrackerInterval(604801)).toBeUndefined();
expect(normalizeTorrentTrackerTimeout('1.5')).toBeUndefined();
});
});
describe('download connection resolution', () => {
it('uses a clamped fallback for legacy rows without a saved value', () => {
expect(resolveDownloadConnections(undefined, 8)).toBe(8);
+28
View File
@@ -65,6 +65,34 @@ export const normalizeTorrentEncryptionPolicy = (
return undefined;
};
export const MAX_TORRENT_TRACKER_TIMEOUT = 604800;
export const MAX_TORRENT_TRACKER_INTERVAL = 604800;
const parseIntegerOption = (value: unknown): number | undefined => {
if (typeof value === 'number') {
return Number.isInteger(value) ? value : undefined;
}
if (typeof value === 'string' && value.trim()) {
const parsed = Number(value);
return Number.isInteger(parsed) ? parsed : undefined;
}
return undefined;
};
export const normalizeTorrentTrackerTimeout = (value: unknown): number | undefined => {
const parsed = parseIntegerOption(value);
return parsed !== undefined && parsed >= 1 && parsed <= MAX_TORRENT_TRACKER_TIMEOUT
? parsed
: undefined;
};
export const normalizeTorrentTrackerInterval = (value: unknown): number | undefined => {
const parsed = parseIntegerOption(value);
return parsed !== undefined && parsed >= 0 && parsed <= MAX_TORRENT_TRACKER_INTERVAL
? parsed
: undefined;
};
// Keep every filename component within the common cross-platform filesystem
// limit. Count UTF-8 bytes because POSIX filesystems enforce bytes, while this
// bound is also conservative for Windows filename components.