mirror of
https://git.sr.ht/~cadence/cloudtube
synced 2024-11-14 12:27:28 +00:00
Proxy captions via new /proxy route
We can add more authorized paths to authorizedPaths if we need more resources to be pulled from the NewLeaf/Invidious backend on the same domain. This route forwards to the client a few headers like Bibliogram https://git.sr.ht/~cadence/bibliogram/tree/ea7cd5d5/item/src/site/api/proxy.js#L28-29 so we can also use this route to possibly proxy videos in the future. We are strict about the url parameter not overriding the NewLeaf/Invidious backend (instanceOrigin) by ensuring fetchURL has instanceOrigin as prefix.
This commit is contained in:
parent
db49bb38b0
commit
eb111a44c4
@ -1,27 +0,0 @@
|
|||||||
/** @type {import("node-fetch").default} */
|
|
||||||
// @ts-ignore
|
|
||||||
const fetch = require("node-fetch")
|
|
||||||
const {getUser} = require("../utils/getuser")
|
|
||||||
const constants = require("../utils/constants.js")
|
|
||||||
|
|
||||||
module.exports = [
|
|
||||||
{
|
|
||||||
route: `/api/v1/captions/(${constants.regex.video_id})`, methods: ["GET"], code: async ({req, fill, url}) => {
|
|
||||||
const instanceOrigin = getUser(req).getSettingsOrDefaults().instance
|
|
||||||
const fetchURL = new URL(`${url.pathname}${url.search}`, instanceOrigin)
|
|
||||||
return fetch(fetchURL.toString()).then(res => {
|
|
||||||
return res.text().then(text => {
|
|
||||||
if (res.status === 200) {
|
|
||||||
// Remove the position annotations that youtube unhelpfully provides
|
|
||||||
text = text.replace(/(--> \S+).*/g, "$1")
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
statusCode: res.status,
|
|
||||||
contentType: res.headers.get("content-type"),
|
|
||||||
content: text
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
27
api/proxy.js
Normal file
27
api/proxy.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const {proxy} = require("pinski/plugins")
|
||||||
|
const {getUser} = require("../utils/getuser")
|
||||||
|
const constants = require("../utils/constants.js")
|
||||||
|
|
||||||
|
// list of paths relative to the backend this route is authorized to serve
|
||||||
|
const authorizedPaths = [`/api/v1/captions/(${constants.regex.video_id})`]
|
||||||
|
|
||||||
|
// headers relayed as-is from the proxied backend to the client
|
||||||
|
const proxiedHeaders = ["content-type", "date", "last-modified", "expires", "cache-control", "accept-ranges", "content-range", "origin", "etag", "content-length", "transfer-encoding"]
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
route: `/proxy`, methods: ["GET"], code: async ({req, fill, url}) => {
|
||||||
|
const instanceOrigin = getUser(req).getSettingsOrDefaults().instance
|
||||||
|
const remotePath = url.searchParams.get("url")
|
||||||
|
const fetchURL = new URL(remotePath, instanceOrigin)
|
||||||
|
if (!fetchURL.toString().startsWith(instanceOrigin) || !authorizedPaths.some(element => fetchURL.pathname.match(new RegExp(`^${element}$`)))) {
|
||||||
|
return {
|
||||||
|
statusCode: 401,
|
||||||
|
content: "CloudTube: Unauthorized",
|
||||||
|
contentType: "text/plain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proxy(fetchURL, {}, (h) => Object.keys(h).filter(key => proxiedHeaders.includes(key)).reduce((res, key) => (res[key] = h[key], res), {}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -174,6 +174,11 @@ module.exports = [
|
|||||||
// rewrite description
|
// rewrite description
|
||||||
video.descriptionHtml = converters.rewriteVideoDescription(video.descriptionHtml, id)
|
video.descriptionHtml = converters.rewriteVideoDescription(video.descriptionHtml, id)
|
||||||
|
|
||||||
|
// rewrite captions urls so they are served on the same domain via the /proxy route
|
||||||
|
for (const caption of video.captions) {
|
||||||
|
caption.url = `/proxy?${new URLSearchParams({"url": caption.url})}`
|
||||||
|
}
|
||||||
|
|
||||||
return render(200, "pug/video.pug", {
|
return render(200, "pug/video.pug", {
|
||||||
url, video, formats, subscribed, instanceOrigin, mediaFragment, autoplay, continuous,
|
url, video, formats, subscribed, instanceOrigin, mediaFragment, autoplay, continuous,
|
||||||
sessionWatched, sessionWatchedNext
|
sessionWatched, sessionWatchedNext
|
||||||
|
Loading…
Reference in New Issue
Block a user