]>
Commit | Line | Data |
---|---|---|
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 | const regex = /bytes=(\d+)-(\d+)/ | |
7 | ||
8 | return async function segmentValidator (segment: Segment) { | |
9 | const filename = basename(segment.url) | |
10 | const captured = regex.exec(segment.range) | |
11 | ||
12 | const range = captured[1] + '-' + captured[2] | |
13 | ||
14 | const hashShouldBe = (await segmentsJSON)[filename][range] | |
15 | if (hashShouldBe === undefined) { | |
16 | throw new Error(`Unknown segment name ${filename}/${range} in segment validator`) | |
17 | } | |
18 | ||
19 | const calculatedSha = bufferToEx(await sha256(segment.data)) | |
20 | if (calculatedSha !== hashShouldBe) { | |
21 | throw new Error( | |
22 | `Hashes does not correspond for segment ${filename}/${range}` + | |
23 | `(expected: ${hashShouldBe} instead of ${calculatedSha})` | |
24 | ) | |
25 | } | |
26 | } | |
27 | } | |
28 | ||
29 | // --------------------------------------------------------------------------- | |
30 | ||
31 | export { | |
32 | segmentValidatorFactory | |
33 | } | |
34 | ||
35 | // --------------------------------------------------------------------------- | |
36 | ||
37 | function fetchSha256Segments (url: string) { | |
38 | return fetch(url) | |
39 | .then(res => res.json()) | |
40 | .catch(err => { | |
41 | console.error('Cannot get sha256 segments', err) | |
42 | return {} | |
43 | }) | |
44 | } | |
45 | ||
46 | function sha256 (data?: ArrayBuffer) { | |
47 | if (!data) return undefined | |
48 | ||
49 | return window.crypto.subtle.digest('SHA-256', data) | |
50 | } | |
51 | ||
52 | // Thanks: https://stackoverflow.com/a/53307879 | |
53 | function bufferToEx (buffer?: ArrayBuffer) { | |
54 | if (!buffer) return '' | |
55 | ||
56 | let s = '' | |
57 | const h = '0123456789abcdef' | |
58 | const o = new Uint8Array(buffer) | |
59 | ||
60 | o.forEach((v: any) => s += h[ v >> 4 ] + h[ v & 15 ]) | |
61 | ||
62 | return s | |
63 | } |