diff options
Diffstat (limited to 'client/src/assets/player/p2p-media-loader/segment-validator.ts')
-rw-r--r-- | client/src/assets/player/p2p-media-loader/segment-validator.ts | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/client/src/assets/player/p2p-media-loader/segment-validator.ts b/client/src/assets/player/p2p-media-loader/segment-validator.ts new file mode 100644 index 000000000..8f4922daa --- /dev/null +++ b/client/src/assets/player/p2p-media-loader/segment-validator.ts | |||
@@ -0,0 +1,56 @@ | |||
1 | import { Segment } from 'p2p-media-loader-core' | ||
2 | import { basename } from 'path' | ||
3 | |||
4 | function segmentValidatorFactory (segmentsSha256Url: string) { | ||
5 | const segmentsJSON = fetchSha256Segments(segmentsSha256Url) | ||
6 | |||
7 | return async function segmentValidator (segment: Segment) { | ||
8 | const segmentName = basename(segment.url) | ||
9 | |||
10 | const hashShouldBe = (await segmentsJSON)[segmentName] | ||
11 | if (hashShouldBe === undefined) { | ||
12 | throw new Error(`Unknown segment name ${segmentName} in segment validator`) | ||
13 | } | ||
14 | |||
15 | const calculatedSha = bufferToEx(await sha256(segment.data)) | ||
16 | if (calculatedSha !== hashShouldBe) { | ||
17 | throw new Error(`Hashes does not correspond for segment ${segmentName} (expected: ${hashShouldBe} instead of ${calculatedSha})`) | ||
18 | } | ||
19 | } | ||
20 | } | ||
21 | |||
22 | // --------------------------------------------------------------------------- | ||
23 | |||
24 | export { | ||
25 | segmentValidatorFactory | ||
26 | } | ||
27 | |||
28 | // --------------------------------------------------------------------------- | ||
29 | |||
30 | function fetchSha256Segments (url: string) { | ||
31 | return fetch(url) | ||
32 | .then(res => res.json()) | ||
33 | .catch(err => { | ||
34 | console.error('Cannot get sha256 segments', err) | ||
35 | return {} | ||
36 | }) | ||
37 | } | ||
38 | |||
39 | function sha256 (data?: ArrayBuffer) { | ||
40 | if (!data) return undefined | ||
41 | |||
42 | return window.crypto.subtle.digest('SHA-256', data) | ||
43 | } | ||
44 | |||
45 | // Thanks: https://stackoverflow.com/a/53307879 | ||
46 | function bufferToEx (buffer?: ArrayBuffer) { | ||
47 | if (!buffer) return '' | ||
48 | |||
49 | let s = '' | ||
50 | const h = '0123456789abcdef' | ||
51 | const o = new Uint8Array(buffer) | ||
52 | |||
53 | o.forEach((v: any) => s += h[ v >> 4 ] + h[ v & 15 ]) | ||
54 | |||
55 | return s | ||
56 | } | ||