diff options
author | Chocobozzz <me@florianbigard.com> | 2023-07-21 17:46:37 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-07-25 11:53:08 +0200 |
commit | f42fcb4b58f146c2e5ace236548a99d361ade55f (patch) | |
tree | afddb566b00a02770043c04257ccd1bc7be3d462 /shared/server-commands | |
parent | 12dc3a942a13c7f1489822dae052da197ef15905 (diff) | |
download | PeerTube-f42fcb4b58f146c2e5ace236548a99d361ade55f.tar.gz PeerTube-f42fcb4b58f146c2e5ace236548a99d361ade55f.tar.zst PeerTube-f42fcb4b58f146c2e5ace236548a99d361ade55f.zip |
Implement video file replacement in client
Diffstat (limited to 'shared/server-commands')
-rw-r--r-- | shared/server-commands/videos/videos-command.ts | 81 |
1 files changed, 42 insertions, 39 deletions
diff --git a/shared/server-commands/videos/videos-command.ts b/shared/server-commands/videos/videos-command.ts index 6c38fa7ef..3fdbc348a 100644 --- a/shared/server-commands/videos/videos-command.ts +++ b/shared/server-commands/videos/videos-command.ts | |||
@@ -462,7 +462,7 @@ export class VideosCommand extends AbstractCommand { | |||
462 | path: string | 462 | path: string |
463 | attributes: { fixture?: string } & { [id: string]: any } | 463 | attributes: { fixture?: string } & { [id: string]: any } |
464 | }): Promise<VideoCreateResult> { | 464 | }): Promise<VideoCreateResult> { |
465 | const { path, attributes, expectedStatus } = options | 465 | const { path, attributes, expectedStatus = HttpStatusCode.OK_200 } = options |
466 | 466 | ||
467 | let size = 0 | 467 | let size = 0 |
468 | let videoFilePath: string | 468 | let videoFilePath: string |
@@ -597,43 +597,47 @@ export class VideosCommand extends AbstractCommand { | |||
597 | const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 }) | 597 | const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 }) |
598 | return new Promise<GotResponse<{ video: VideoCreateResult }>>((resolve, reject) => { | 598 | return new Promise<GotResponse<{ video: VideoCreateResult }>>((resolve, reject) => { |
599 | readable.on('data', async function onData (chunk) { | 599 | readable.on('data', async function onData (chunk) { |
600 | readable.pause() | 600 | try { |
601 | 601 | readable.pause() | |
602 | const headers = { | 602 | |
603 | 'Authorization': 'Bearer ' + token, | 603 | const headers = { |
604 | 'Content-Type': 'application/octet-stream', | 604 | 'Authorization': 'Bearer ' + token, |
605 | 'Content-Range': contentRangeBuilder | 605 | 'Content-Type': 'application/octet-stream', |
606 | ? contentRangeBuilder(start, chunk) | 606 | 'Content-Range': contentRangeBuilder |
607 | : `bytes ${start}-${start + chunk.length - 1}/${size}`, | 607 | ? contentRangeBuilder(start, chunk) |
608 | 'Content-Length': contentLength ? contentLength + '' : chunk.length + '' | 608 | : `bytes ${start}-${start + chunk.length - 1}/${size}`, |
609 | 'Content-Length': contentLength ? contentLength + '' : chunk.length + '' | ||
610 | } | ||
611 | |||
612 | if (digestBuilder) { | ||
613 | Object.assign(headers, { digest: digestBuilder(chunk) }) | ||
614 | } | ||
615 | |||
616 | const res = await got<{ video: VideoCreateResult }>({ | ||
617 | url, | ||
618 | method: 'put', | ||
619 | headers, | ||
620 | path: path + '?' + pathUploadId, | ||
621 | body: chunk, | ||
622 | responseType: 'json', | ||
623 | throwHttpErrors: false | ||
624 | }) | ||
625 | |||
626 | start += chunk.length | ||
627 | |||
628 | if (res.statusCode === expectedStatus) { | ||
629 | return resolve(res) | ||
630 | } | ||
631 | |||
632 | if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) { | ||
633 | readable.off('data', onData) | ||
634 | return reject(new Error('Incorrect transient behaviour sending intermediary chunks')) | ||
635 | } | ||
636 | |||
637 | readable.resume() | ||
638 | } catch (err) { | ||
639 | reject(err) | ||
609 | } | 640 | } |
610 | |||
611 | if (digestBuilder) { | ||
612 | Object.assign(headers, { digest: digestBuilder(chunk) }) | ||
613 | } | ||
614 | |||
615 | const res = await got<{ video: VideoCreateResult }>({ | ||
616 | url, | ||
617 | method: 'put', | ||
618 | headers, | ||
619 | path: path + '?' + pathUploadId, | ||
620 | body: chunk, | ||
621 | responseType: 'json', | ||
622 | throwHttpErrors: false | ||
623 | }) | ||
624 | |||
625 | start += chunk.length | ||
626 | |||
627 | if (res.statusCode === expectedStatus) { | ||
628 | return resolve(res) | ||
629 | } | ||
630 | |||
631 | if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) { | ||
632 | readable.off('data', onData) | ||
633 | return reject(new Error('Incorrect transient behaviour sending intermediary chunks')) | ||
634 | } | ||
635 | |||
636 | readable.resume() | ||
637 | }) | 641 | }) |
638 | }) | 642 | }) |
639 | } | 643 | } |
@@ -695,8 +699,7 @@ export class VideosCommand extends AbstractCommand { | |||
695 | ...options, | 699 | ...options, |
696 | 700 | ||
697 | path: '/api/v1/videos/' + options.videoId + '/source/replace-resumable', | 701 | path: '/api/v1/videos/' + options.videoId + '/source/replace-resumable', |
698 | attributes: { fixture: options.fixture }, | 702 | attributes: { fixture: options.fixture } |
699 | expectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
700 | }) | 703 | }) |
701 | } | 704 | } |
702 | 705 | ||