Fix updating hls infohash on privacy update

pull/6527/head
Chocobozzz 2024-07-31 09:26:54 +02:00
parent 44919a8d57
commit 22e9d9a1fe
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
4 changed files with 49 additions and 39 deletions

View File

@ -1,7 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { expect } from 'chai'
import { basename } from 'path'
import { getAllFiles, getHLS } from '@peertube/peertube-core-utils'
import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@peertube/peertube-models'
import { areScalewayObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
@ -20,7 +18,9 @@ import {
} from '@peertube/peertube-server-commands'
import { expectStartWith } from '@tests/shared/checks.js'
import { SQLCommand } from '@tests/shared/sql-command.js'
import { checkVideoFileTokenReinjection } from '@tests/shared/streaming-playlists.js'
import { checkPlaylistInfohash, checkVideoFileTokenReinjection } from '@tests/shared/streaming-playlists.js'
import { expect } from 'chai'
import { basename } from 'path'
function extractFilenameFromUrl (url: string) {
const parts = basename(url).split(':')
@ -74,6 +74,8 @@ describe('Object storage for video static file privacy', function () {
await makeRawRequest({ url: file.fileUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
}
await checkPlaylistInfohash({ video, files: hls.files, sqlCommand })
}
}

View File

@ -1,11 +1,7 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import bytes from 'bytes'
import { expect } from 'chai'
import { stat } from 'fs/promises'
import merge from 'lodash-es/merge.js'
import { HttpStatusCode, VideoDetails } from '@peertube/peertube-models'
import { areMockObjectStorageTestsDisabled, sha1 } from '@peertube/peertube-node-utils'
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
import {
cleanupTests,
createMultipleServers,
@ -18,12 +14,17 @@ import {
setAccessTokensToServers,
waitJobs
} from '@peertube/peertube-server-commands'
import { expectStartWith, expectLogDoesNotContain } from '@tests/shared/checks.js'
import { expectLogDoesNotContain, expectStartWith } from '@tests/shared/checks.js'
import { checkTmpIsEmpty } from '@tests/shared/directories.js'
import { generateHighBitrateVideo } from '@tests/shared/generate.js'
import { MockObjectStorageProxy } from '@tests/shared/mock-servers/mock-object-storage.js'
import { SQLCommand } from '@tests/shared/sql-command.js'
import { checkPlaylistInfohash } from '@tests/shared/streaming-playlists.js'
import { checkWebTorrentWorks } from '@tests/shared/webtorrent.js'
import bytes from 'bytes'
import { expect } from 'chai'
import { stat } from 'fs/promises'
import merge from 'lodash-es/merge.js'
async function checkFiles (options: {
server: PeerTubeServer
@ -91,7 +92,6 @@ async function checkFiles (options: {
const resSha = await makeRawRequest({ url: hls.segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 })
expect(JSON.stringify(resSha.body)).to.not.throw
let i = 0
for (const file of hls.files) {
expectStartWith(file.fileUrl, start)
@ -100,15 +100,10 @@ async function checkFiles (options: {
expectStartWith(location, start)
await makeRawRequest({ url: location, expectedStatus: HttpStatusCode.OK_200 })
}
if (originServer.internalServerNumber === server.internalServerNumber) {
const infohash = sha1(`${2 + hls.playlistUrl}+V${i}`)
const dbInfohashes = await originSQLCommand.getPlaylistInfohash(hls.id)
expect(dbInfohashes).to.include(infohash)
}
i++
if (originServer.internalServerNumber === server.internalServerNumber) {
await checkPlaylistInfohash({ video, files: hls.files, sqlCommand: originSQLCommand })
}
}

View File

@ -1,22 +1,24 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { expect } from 'chai'
import { basename, dirname, join } from 'path'
import { removeFragmentedMP4Ext, uuidRegex } from '@peertube/peertube-core-utils'
import { getHLS, removeFragmentedMP4Ext, uuidRegex } from '@peertube/peertube-core-utils'
import {
HttpStatusCode,
VideoDetails,
VideoPrivacy,
VideoResolution,
VideoStreamingPlaylist,
VideoStreamingPlaylistType
} from '@peertube/peertube-models'
import { sha256 } from '@peertube/peertube-node-utils'
import { sha1, sha256 } from '@peertube/peertube-node-utils'
import { makeRawRequest, PeerTubeServer } from '@peertube/peertube-server-commands'
import { expect } from 'chai'
import { basename, dirname, join } from 'path'
import { expectStartWith } from './checks.js'
import { SQLCommand } from './sql-command.js'
import { hlsInfohashExist } from './tracker.js'
import { checkWebTorrentWorks } from './webtorrent.js'
async function checkSegmentHash (options: {
export async function checkSegmentHash (options: {
server: PeerTubeServer
baseUrlPlaylist: string
baseUrlSegment: string
@ -49,9 +51,7 @@ async function checkSegmentHash (options: {
expect(sha256(segmentBody)).to.equal(shaBody[videoName][range], `Invalid sha256 result for ${videoName} range ${range}`)
}
// ---------------------------------------------------------------------------
async function checkLiveSegmentHash (options: {
export async function checkLiveSegmentHash (options: {
server: PeerTubeServer
baseUrlSegment: string
videoUUID: string
@ -68,9 +68,25 @@ async function checkLiveSegmentHash (options: {
expect(sha256(segmentBody)).to.equal(shaBody[segmentName])
}
export async function checkPlaylistInfohash (options: {
video: VideoDetails
sqlCommand: SQLCommand
files: unknown[]
}) {
const { sqlCommand, video, files } = options
const hls = getHLS(video)
for (let i = 0; i < files.length; i++) {
const infohash = sha1(`${2 + hls.playlistUrl}+V${i}`)
const dbInfohashes = await sqlCommand.getPlaylistInfohash(hls.id)
expect(dbInfohashes).to.include(infohash)
}
}
// ---------------------------------------------------------------------------
async function checkResolutionsInMasterPlaylist (options: {
export async function checkResolutionsInMasterPlaylist (options: {
server: PeerTubeServer
playlistUrl: string
resolutions: number[]
@ -98,7 +114,7 @@ async function checkResolutionsInMasterPlaylist (options: {
expect(playlistsLength).to.have.lengthOf(resolutions.length)
}
async function completeCheckHlsPlaylist (options: {
export async function completeCheckHlsPlaylist (options: {
servers: PeerTubeServer[]
videoUUID: string
hlsOnly: boolean
@ -255,7 +271,7 @@ async function completeCheckHlsPlaylist (options: {
}
}
async function checkVideoFileTokenReinjection (options: {
export async function checkVideoFileTokenReinjection (options: {
server: PeerTubeServer
videoUUID: string
videoFileToken: string
@ -295,16 +311,7 @@ async function checkVideoFileTokenReinjection (options: {
}
}
function extractResolutionPlaylistUrls (masterPath: string, masterContent: string) {
export function extractResolutionPlaylistUrls (masterPath: string, masterContent: string) {
return masterContent.match(/^([^.]+\.m3u8.*)/mg)
.map(filename => join(dirname(masterPath), filename))
}
export {
checkSegmentHash,
checkLiveSegmentHash,
checkResolutionsInMasterPlaylist,
completeCheckHlsPlaylist,
extractResolutionPlaylistUrls,
checkVideoFileTokenReinjection
}

View File

@ -125,6 +125,12 @@ export async function addVideoJobsAfterUpdate (options: {
const jobs: CreateJobArgument[] = []
const filePathChanged = await moveFilesIfPrivacyChanged(video, oldPrivacy)
const hls = video.getHLSPlaylist()
if (filePathChanged && hls) {
hls.assignP2PMediaLoaderInfoHashes(video, hls.VideoFiles)
await hls.save()
}
if (!video.isLive && (nameChanged || filePathChanged)) {
for (const file of (video.VideoFiles || [])) {