allow limiting video-comments rss feeds to an account or video channel
[oweals/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   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 }