]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/assets/player/p2p-media-loader/segment-validator.ts
8f4922daa040f0ec6e1ec3bc01eba5c8229c3e97
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / p2p-media-loader / segment-validator.ts
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 }