X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fobject-storage-proxy.ts;h=6bff05f14052d9237cd35cecbe65d35114cfc5b0;hb=09f3d81e0c8edebbe8f5698811ecfb165f942378;hp=3ce279671415596c15e2a3e9a42e292ccc8b7c66;hpb=5a122dddc5aab1b2ae1843411032d5f392bdd216;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/object-storage-proxy.ts b/server/controllers/object-storage-proxy.ts index 3ce279671..6bff05f14 100644 --- a/server/controllers/object-storage-proxy.ts +++ b/server/controllers/object-storage-proxy.ts @@ -1,7 +1,10 @@ import cors from 'cors' import express from 'express' +import { PassThrough, pipeline } from 'stream' import { logger } from '@server/helpers/logger' +import { StreamReplacer } from '@server/helpers/stream-replacer' import { OBJECT_STORAGE_PROXY_PATHS } from '@server/initializers/constants' +import { injectQueryToPlaylistUrls } from '@server/lib/hls' import { getHLSFileReadStream, getWebTorrentFileReadStream } from '@server/lib/object-storage' import { asyncMiddleware, @@ -11,6 +14,8 @@ import { optionalAuthenticate } from '@server/middlewares' import { HttpStatusCode } from '@shared/models' +import { buildReinjectVideoFileTokenQuery, doReinjectVideoFileToken } from './shared/m3u8-playlist' +import { GetObjectCommandOutput } from '@aws-sdk/client-s3' const objectStorageProxyRouter = express.Router() @@ -42,11 +47,13 @@ async function proxifyWebTorrent (req: express.Request, res: express.Response) { logger.debug('Proxifying WebTorrent file %s from object storage.', filename) try { - const stream = await getWebTorrentFileReadStream({ + const { response: s3Response, stream } = await getWebTorrentFileReadStream({ filename, rangeHeader: req.header('range') }) + setS3Headers(res, s3Response) + return stream.pipe(res) } catch (err) { return handleObjectStorageFailure(res, err) @@ -61,13 +68,28 @@ async function proxifyHLS (req: express.Request, res: express.Response) { logger.debug('Proxifying HLS file %s from object storage.', filename) try { - const stream = await getHLSFileReadStream({ + const { response: s3Response, stream } = await getHLSFileReadStream({ playlist: playlist.withVideo(video), filename, rangeHeader: req.header('range') }) - return stream.pipe(res) + setS3Headers(res, s3Response) + + const streamReplacer = filename.endsWith('.m3u8') && doReinjectVideoFileToken(req) + ? new StreamReplacer(line => injectQueryToPlaylistUrls(line, buildReinjectVideoFileTokenQuery(req, filename.endsWith('master.m3u8')))) + : new PassThrough() + + return pipeline( + stream, + streamReplacer, + res, + err => { + if (!err) return + + handleObjectStorageFailure(res, err) + } + ) } catch (err) { return handleObjectStorageFailure(res, err) } @@ -75,6 +97,7 @@ async function proxifyHLS (req: express.Request, res: express.Response) { function handleObjectStorageFailure (res: express.Response, err: Error) { if (err.name === 'NoSuchKey') { + logger.debug('Could not find key in object storage to proxify private HLS video file.', { err }) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) } @@ -84,3 +107,9 @@ function handleObjectStorageFailure (res: express.Response, err: Error) { type: err.name }) } + +function setS3Headers (res: express.Response, s3Response: GetObjectCommandOutput) { + if (s3Response.$metadata.httpStatusCode === HttpStatusCode.PARTIAL_CONTENT_206) { + res.status(HttpStatusCode.PARTIAL_CONTENT_206) + } +}