]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/controllers/object-storage-proxy.ts
Clearer changelog
[github/Chocobozzz/PeerTube.git] / server / controllers / object-storage-proxy.ts
CommitLineData
9ab330b9
C
1import cors from 'cors'
2import express from 'express'
71e3e879 3import { PassThrough, pipeline } from 'stream'
5a122ddd 4import { logger } from '@server/helpers/logger'
71e3e879 5import { StreamReplacer } from '@server/helpers/stream-replacer'
9ab330b9 6import { OBJECT_STORAGE_PROXY_PATHS } from '@server/initializers/constants'
71e3e879 7import { injectQueryToPlaylistUrls } from '@server/lib/hls'
9ab330b9
C
8import { getHLSFileReadStream, getWebTorrentFileReadStream } from '@server/lib/object-storage'
9import {
10 asyncMiddleware,
11 ensureCanAccessPrivateVideoHLSFiles,
12 ensureCanAccessVideoPrivateWebTorrentFiles,
5a122ddd 13 ensurePrivateObjectStorageProxyIsEnabled,
9ab330b9
C
14 optionalAuthenticate
15} from '@server/middlewares'
16import { HttpStatusCode } from '@shared/models'
71e3e879 17import { buildReinjectVideoFileTokenQuery, doReinjectVideoFileToken } from './shared/m3u8-playlist'
9ab330b9
C
18
19const objectStorageProxyRouter = express.Router()
20
21objectStorageProxyRouter.use(cors())
22
23objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.PRIVATE_WEBSEED + ':filename',
5a122ddd 24 ensurePrivateObjectStorageProxyIsEnabled,
9ab330b9
C
25 optionalAuthenticate,
26 asyncMiddleware(ensureCanAccessVideoPrivateWebTorrentFiles),
27 asyncMiddleware(proxifyWebTorrent)
28)
29
30objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS + ':videoUUID/:filename',
5a122ddd 31 ensurePrivateObjectStorageProxyIsEnabled,
9ab330b9
C
32 optionalAuthenticate,
33 asyncMiddleware(ensureCanAccessPrivateVideoHLSFiles),
34 asyncMiddleware(proxifyHLS)
35)
36
37// ---------------------------------------------------------------------------
38
39export {
40 objectStorageProxyRouter
41}
42
43async function proxifyWebTorrent (req: express.Request, res: express.Response) {
44 const filename = req.params.filename
45
5a122ddd
C
46 logger.debug('Proxifying WebTorrent file %s from object storage.', filename)
47
9ab330b9
C
48 try {
49 const stream = await getWebTorrentFileReadStream({
50 filename,
51 rangeHeader: req.header('range')
52 })
53
54 return stream.pipe(res)
55 } catch (err) {
56 return handleObjectStorageFailure(res, err)
57 }
58}
59
60async function proxifyHLS (req: express.Request, res: express.Response) {
61 const playlist = res.locals.videoStreamingPlaylist
62 const video = res.locals.onlyVideo
63 const filename = req.params.filename
64
5a122ddd
C
65 logger.debug('Proxifying HLS file %s from object storage.', filename)
66
9ab330b9
C
67 try {
68 const stream = await getHLSFileReadStream({
69 playlist: playlist.withVideo(video),
70 filename,
71 rangeHeader: req.header('range')
72 })
73
71e3e879
C
74 const streamReplacer = filename.endsWith('.m3u8') && doReinjectVideoFileToken(req)
75 ? new StreamReplacer(line => injectQueryToPlaylistUrls(line, buildReinjectVideoFileTokenQuery(req)))
76 : new PassThrough()
77
78 return pipeline(
79 stream,
80 streamReplacer,
81 res,
82 err => {
83 if (!err) return
84
85 handleObjectStorageFailure(res, err)
86 }
87 )
9ab330b9
C
88 } catch (err) {
89 return handleObjectStorageFailure(res, err)
90 }
91}
92
93function handleObjectStorageFailure (res: express.Response, err: Error) {
94 if (err.name === 'NoSuchKey') {
71e3e879 95 logger.debug('Could not find key in object storage to proxify private HLS video file.', { err })
9ab330b9
C
96 return res.sendStatus(HttpStatusCode.NOT_FOUND_404)
97 }
98
99 return res.fail({
100 status: HttpStatusCode.INTERNAL_SERVER_ERROR_500,
101 message: err.message,
102 type: err.name
103 })
104}