From 1c87da7050af38dae6920fdd59b3a018e23324bc Mon Sep 17 00:00:00 2001 From: 11tuvork28 Date: Thu, 23 Feb 2023 16:12:07 +0100 Subject: [PATCH 1/2] Add proxy_domains to config/config example --- config/config.example.yml | 16 ++++++++++++++++ src/invidious/config.cr | 2 ++ 2 files changed, 18 insertions(+) diff --git a/config/config.example.yml b/config/config.example.yml index 8abe1b9e..3e9865a8 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -97,6 +97,22 @@ db: ## domain: +## +## A list of domains where external proxy servers. This is used +## to build the urls used for proxing videos. +## When none is set invidious will be used for proxiying. +## This generally only needs to be set for bigger instances, +## a example proxy url would be like ['proxy.example.com']. +## Using a list urls might look like this: +## ['proxy-eu1.example.com','proxy-eu2.example.com'] +## Invidious would then choose at random which request gets one +## of the proxy servers +## +## Accepted values: a list of fully qualified domain names (FQDN) +## Default: [""] +## +proxy_domains: [""] + ## ## Tell Invidious that it is behind a proxy that provides only ## HTTPS, so all links must use the https:// scheme. This diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 9fc58409..edee6d33 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -88,6 +88,8 @@ class Config property hmac_key : String? # Domain to be used for links to resources on the site where an absolute URL is required property domain : String? + # Domain list of external proxy servers to be used, when multiple are set they will be randomly choosen + property proxy_domains : Array(String) = [] of String # Subscribe to channels using PubSubHubbub (requires domain, hmac_key) property use_pubsub_feeds : Bool | Int32 = false property popular_enabled : Bool = true From 10c06ded9036a0e52305403c9b1a710c30188ecf Mon Sep 17 00:00:00 2001 From: 11tuvork28 Date: Thu, 23 Feb 2023 17:13:58 +0100 Subject: [PATCH 2/2] Added proxiyng for videos with a given list of domains --- src/invidious/routes/api/manifest.cr | 23 +++++++++++++++++++---- src/invidious/routes/video_playback.cr | 7 ++++++- src/invidious/routes/watch.cr | 10 ++++++++-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr index 662d1002..6a8cee89 100644 --- a/src/invidious/routes/api/manifest.cr +++ b/src/invidious/routes/api/manifest.cr @@ -7,6 +7,11 @@ module Invidious::Routes::API::Manifest local = env.params.query["local"]?.try &.== "true" id = env.params.url["id"] region = env.params.query["region"]? + proxy_url = HOST_URL + + if CONFIG.proxy_domains.size > 0 && local + proxy_url = ("https:///" + CONFIG.proxy_domains.[Random.rand(CONFIG.proxy_domains.size)]) + end # Since some implementations create playlists based on resolution regardless of different codecs, # we can opt to only add a source to a representation if it has a unique height within that representation @@ -29,7 +34,7 @@ module Invidious::Routes::API::Manifest if local uri = URI.parse(url) - url = "#{HOST_URL}#{uri.request_target}host/#{uri.host}/" + url = "#{proxy_url}#{uri.request_target}host/#{uri.host}/" end "#{url}" @@ -42,7 +47,7 @@ module Invidious::Routes::API::Manifest if local adaptive_fmts.each do |fmt| - fmt["url"] = JSON::Any.new("#{HOST_URL}#{URI.parse(fmt["url"].as_s).request_target}") + fmt["url"] = JSON::Any.new("#{proxy_url}#{URI.parse(fmt["url"].as_s).request_target}") end end @@ -164,6 +169,11 @@ module Invidious::Routes::API::Manifest end local = env.params.query["local"]?.try &.== "true" + proxy_url = HOST_URL + + if CONFIG.proxy_domains.size > 0 && local + proxy_url = ("https:///" + CONFIG.proxy_domains.[Random.rand(CONFIG.proxy_domains.size)]) + end env.response.content_type = "application/x-mpegURL" env.response.headers.add("Access-Control-Allow-Origin", "*") @@ -203,7 +213,7 @@ module Invidious::Routes::API::Manifest raw_params["local"] = "true" - "#{HOST_URL}/videoplayback?#{raw_params}" + "#{proxy_url}/videoplayback?#{raw_params}" end end @@ -219,6 +229,11 @@ module Invidious::Routes::API::Manifest end local = env.params.query["local"]?.try &.== "true" + proxy_url = HOST_URL + + if CONFIG.proxy_domains.size > 0 && local + proxy_url = ("https:///" + CONFIG.proxy_domains.[Random.rand(CONFIG.proxy_domains.size)]) + end env.response.content_type = "application/x-mpegURL" env.response.headers.add("Access-Control-Allow-Origin", "*") @@ -226,7 +241,7 @@ module Invidious::Routes::API::Manifest manifest = response.body if local - manifest = manifest.gsub("https://www.youtube.com", HOST_URL) + manifest = manifest.gsub("https://www.youtube.com", proxy_url) manifest = manifest.gsub("index.m3u8", "index.m3u8?local=true") end diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr index 1e932d11..0f7dad4b 100644 --- a/src/invidious/routes/video_playback.cr +++ b/src/invidious/routes/video_playback.cr @@ -262,6 +262,11 @@ module Invidious::Routes::VideoPlayback region = env.params.query["region"]? local = (env.params.query["local"]? == "true") + proxy_url = HOST_URL + + if CONFIG.proxy_domains.size > 0 && local + proxy_url = ("https:///" + CONFIG.proxy_domains.[Random.rand(CONFIG.proxy_domains.size)]) + end title = env.params.query["title"]? @@ -285,7 +290,7 @@ module Invidious::Routes::VideoPlayback end if local - url = URI.parse(url).request_target.not_nil! + url = proxy_url + URI.parse(url).request_target.not_nil! url += "&title=#{URI.encode_www_form(title, space_to_plus: false)}" if title end diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr index 5d3845c3..6022ffff 100644 --- a/src/invidious/routes/watch.cr +++ b/src/invidious/routes/watch.cr @@ -129,8 +129,14 @@ module Invidious::Routes::Watch adaptive_fmts = video.adaptive_fmts if params.local - fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } - adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } + proxy_url = HOST_URL + + if CONFIG.proxy_domains.size > 0 && params.local + proxy_url = ("https:///" + CONFIG.proxy_domains.[Random.rand(CONFIG.proxy_domains.size)]) + end + + fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(proxy_url + URI.parse(fmt["url"].as_s).request_target) } + adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(proxy_url + URI.parse(fmt["url"].as_s).request_target) } end video_streams = video.video_streams