External Proxies: Rotate between proxies with balance enabled

Closes #17
This commit is contained in:
Fijxu 2024-10-30 01:59:08 -03:00
parent 486c5845cd
commit 26bee068eb
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
3 changed files with 39 additions and 12 deletions

View file

@ -390,7 +390,7 @@ def gen_videoplayback_proxy_list
if !CONFIG.external_videoplayback_proxy.empty? if !CONFIG.external_videoplayback_proxy.empty?
external_videoplayback_proxy = "" external_videoplayback_proxy = ""
CONFIG.external_videoplayback_proxy.each do |proxy| CONFIG.external_videoplayback_proxy.each do |proxy|
external_videoplayback_proxy += " #{proxy}" external_videoplayback_proxy += " #{proxy[:url]}"
end end
else else
external_videoplayback_proxy = "" external_videoplayback_proxy = ""

View file

@ -4,25 +4,51 @@ module Invidious::HttpServer
module Utils module Utils
extend self extend self
@@proxy_alive : String = "" @@proxy_list : Array(String) = [] of String
@@current_proxy : String = ""
@@count : Int64 = Time.utc.to_unix
def check_external_proxy def check_external_proxy
CONFIG.external_videoplayback_proxy.each do |proxy| CONFIG.external_videoplayback_proxy.each do |proxy|
begin begin
response = HTTP::Client.get(proxy) response = HTTP::Client.get("#{proxy[:url]}/health")
if response.status_code == 200 if response.status_code == 200
@@proxy_alive = proxy if @@proxy_list.includes?(proxy[:url])
LOGGER.debug("CheckExternalProxy: Proxy set to: '#{proxy}'") next
break end
if proxy[:balance]
@@proxy_list << proxy[:url]
LOGGER.debug("CheckExternalProxy: Adding proxy '#{proxy[:url]}' to the list of proxies")
end
break if proxy[:balance] == false && !@@proxy_list.empty?
@@proxy_list << proxy[:url]
end end
rescue rescue
LOGGER.debug("CheckExternalProxy: Proxy '#{proxy}' is not available") if @@proxy_list.includes?(proxy[:url])
LOGGER.debug("CheckExternalProxy: Proxy '#{proxy[:url]}' is not available, removing it from the list of proxies")
@@proxy_list.delete(proxy[:url])
end
LOGGER.debug("CheckExternalProxy: Proxy '#{proxy[:url]}' is not available")
end end
end end
LOGGER.trace("CheckExternalProxy: List of proxies:")
LOGGER.trace("#{@@proxy_list.inspect}")
end
# TODO: If the function is called many times, it will return a random
# proxy from the list. That is not how it should be.
# It should return the same proxy, in multiple function calls
def select_proxy
if (@@count - (Time.utc.to_unix - 30)) <= 0
return if @@proxy_list.size <= 0
@@current_proxy = @@proxy_list[Random.rand(@@proxy_list.size)]
LOGGER.debug("Current proxy is: '#{@@current_proxy}'")
@@count = Time.utc.to_unix
end
end end
def get_external_proxy def get_external_proxy
return @@proxy_alive return @@current_proxy
end end
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)
@ -35,8 +61,8 @@ module Invidious::HttpServer
url.query_params = params url.query_params = params
if absolute if absolute
if !@@proxy_alive.empty? if !(proxy = get_external_proxy()).empty?
return "#{@@proxy_alive}#{url.request_target}" return "#{proxy}#{url.request_target}"
else else
return "#{HOST_URL}#{url.request_target}" return "#{HOST_URL}#{url.request_target}"
end end

View file

@ -5,8 +5,9 @@ class Invidious::Jobs::CheckExternalProxy < Invidious::Jobs::BaseJob
def begin def begin
loop do loop do
HttpServer::Utils.check_external_proxy HttpServer::Utils.check_external_proxy
LOGGER.info("CheckExternalProxy: Done, sleeping for 1 minute") HttpServer::Utils.select_proxy
sleep 1.minutes LOGGER.info("CheckExternalProxy: Done, sleeping for 15 seconds")
sleep 15.seconds
Fiber.yield Fiber.yield
end end
end end