diff --git a/src/invidious/http_server/utils.cr b/src/invidious/http_server/utils.cr index 623a9177..c42a832f 100644 --- a/src/invidious/http_server/utils.cr +++ b/src/invidious/http_server/utils.cr @@ -4,7 +4,7 @@ module Invidious::HttpServer module Utils extend self - def proxy_video_url(raw_url : String, *, region : String? = nil, absolute : Bool = false) + def proxy_video_url(raw_url : String, *, region : String? = nil, absolute : Bool = false, host : String? = "") url = URI.parse(raw_url) # Add some URL parameters @@ -14,7 +14,7 @@ module Invidious::HttpServer url.query_params = params if absolute - return "#{HOST_URL}#{url.request_target}" + return "#{host}#{url.request_target}" else return url.request_target end diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr index bddf97cb..425a92cc 100644 --- a/src/invidious/routes/api/manifest.cr +++ b/src/invidious/routes/api/manifest.cr @@ -1,6 +1,8 @@ module Invidious::Routes::API::Manifest # /api/manifest/dash/id/:id def self.get_dash_video_id(env) + host = env.request.headers["Host"] + env.response.headers.add("Access-Control-Allow-Origin", "*") env.response.content_type = "application/dash+xml" @@ -36,7 +38,7 @@ module Invidious::Routes::API::Manifest # Other API clients can get the original URLs by omiting `local=true`. manifest = response.body.gsub(/[^<]+<\/BaseURL>/) do |baseurl| url = baseurl.lchop("").rchop("") - url = HttpServer::Utils.proxy_video_url(url, absolute: true) if local + url = HttpServer::Utils.proxy_video_url(url, absolute: true, host: host) if local "#{url}" end @@ -46,7 +48,7 @@ module Invidious::Routes::API::Manifest # Ditto, only proxify URLs if `local=true` is used if local video.adaptive_fmts.each do |fmt| - fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, absolute: true)) + fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, absolute: true, host: host)) end end diff --git a/src/invidious/routes/embed.cr b/src/invidious/routes/embed.cr index 930e4915..99199268 100644 --- a/src/invidious/routes/embed.cr +++ b/src/invidious/routes/embed.cr @@ -34,6 +34,7 @@ module Invidious::Routes::Embed def self.show(env) locale = env.get("preferences").as(Preferences).locale + host = env.request.headers["Host"] id = env.params.url["id"] plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") @@ -161,11 +162,11 @@ module Invidious::Routes::Embed adaptive_fmts = video.adaptive_fmts if params.local - fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) } + fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, host: host)) } end # Always proxy DASH streams, otherwise youtube CORS headers will prevent playback - adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) } + adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, host: host)) } video_streams = video.video_streams audio_streams = video.audio_streams diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr index 083087a9..5368df68 100644 --- a/src/invidious/routes/video_playback.cr +++ b/src/invidious/routes/video_playback.cr @@ -2,6 +2,7 @@ module Invidious::Routes::VideoPlayback # /videoplayback def self.get_video_playback(env) locale = env.get("preferences").as(Preferences).locale + host_ = env.request.headers["Host"] query_params = env.params.query fvip = query_params["fvip"]? || "3" @@ -107,7 +108,7 @@ module Invidious::Routes::VideoPlayback env.response.headers["Access-Control-Allow-Origin"] = "*" if location = resp.headers["Location"]? - url = Invidious::HttpServer::Utils.proxy_video_url(location, region: region) + url = Invidious::HttpServer::Utils.proxy_video_url(location, region: region, host: host_) return env.redirect url end @@ -165,7 +166,7 @@ module Invidious::Routes::VideoPlayback env.response.headers["Access-Control-Allow-Origin"] = "*" if location = resp.headers["Location"]? - url = Invidious::HttpServer::Utils.proxy_video_url(location, region: region) + url = Invidious::HttpServer::Utils.proxy_video_url(location, region: region, host: host_) if title = query_params["title"]? url = "#{url}&title=#{URI.encode_www_form(title)}" diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr index e777b3f1..d34eb33d 100644 --- a/src/invidious/routes/watch.cr +++ b/src/invidious/routes/watch.cr @@ -4,6 +4,7 @@ module Invidious::Routes::Watch def self.handle(env) locale = env.get("preferences").as(Preferences).locale region = env.params.query["region"]? + host = env.request.headers["Host"] if env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+") url = "/watch?" + env.params.query.to_s.gsub("%20", "").delete("+") @@ -121,11 +122,11 @@ module Invidious::Routes::Watch adaptive_fmts = video.adaptive_fmts if params.local - fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) } + fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, host: host)) } end # Always proxy DASH streams, otherwise youtube CORS headers will prevent playback - adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) } + adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s, host: host)) } video_streams = video.video_streams audio_streams = video.audio_streams