Use HTTP pools for image requests to YouTube

This commit is contained in:
syeopite 2023-12-08 18:20:17 -08:00 committed by Fijxu
parent 201d9ab743
commit c23d85c6e5
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
3 changed files with 25 additions and 17 deletions

View file

@ -115,6 +115,14 @@ SOFTWARE = {
YT_POOL = YoutubeConnectionPool.new(YT_URL, capacity: CONFIG.pool_size) YT_POOL = YoutubeConnectionPool.new(YT_URL, capacity: CONFIG.pool_size)
# Image request pool
GGPHT_POOL = YoutubeConnectionPool.new(URI.parse("https://yt3.ggpht.com"), capacity: CONFIG.pool_size)
# Mapping of subdomain => YoutubeConnectionPool
# This is needed as we may need to access arbitrary subdomains of ytimg
YTIMG_POOLS = {} of String => YoutubeConnectionPool
# CLI # CLI
Kemal.config.extra_options do |parser| Kemal.config.extra_options do |parser|
parser.banner = "Usage: invidious [arguments]" parser.banner = "Usage: invidious [arguments]"

View file

@ -32,7 +32,7 @@ module Invidious::Routes::Images
} }
begin begin
HTTP::Client.get("https://yt3.ggpht.com#{url}") do |resp| GGPHT_POOL.client &.get(url) do |resp|
return request_proc.call(resp) return request_proc.call(resp)
end end
rescue ex rescue ex
@ -80,7 +80,7 @@ module Invidious::Routes::Images
} }
begin begin
HTTP::Client.get("https://#{authority}.ytimg.com#{url}") do |resp| get_ytimg_pool(authority).client &.get(url) do |resp|
return request_proc.call(resp) return request_proc.call(resp)
end end
rescue ex rescue ex
@ -119,7 +119,7 @@ module Invidious::Routes::Images
} }
begin begin
HTTP::Client.get("https://i9.ytimg.com#{url}") do |resp| get_ytimg_pool("i9").client &.get(url) do |resp|
return request_proc.call(resp) return request_proc.call(resp)
end end
rescue ex rescue ex
@ -165,8 +165,7 @@ module Invidious::Routes::Images
if name == "maxres.jpg" if name == "maxres.jpg"
build_thumbnails(id).each do |thumb| build_thumbnails(id).each do |thumb|
thumbnail_resource_path = "/vi/#{id}/#{thumb[:url]}.jpg" thumbnail_resource_path = "/vi/#{id}/#{thumb[:url]}.jpg"
# This can likely be optimized into a (small) pool sometime in the future. if get_ytimg_pool("i9").client &.head(thumbnail_resource_path).status_code == 200
if HTTP::Client.head("https://i.ytimg.com#{thumbnail_resource_path}").status_code == 200
name = thumb[:url] + ".jpg" name = thumb[:url] + ".jpg"
break break
end end
@ -199,8 +198,7 @@ module Invidious::Routes::Images
} }
begin begin
# This can likely be optimized into a (small) pool sometime in the future. get_ytimg_pool("i").client &.get(url) do |resp|
HTTP::Client.get("https://i.ytimg.com#{url}") do |resp|
return request_proc.call(resp) return request_proc.call(resp)
end end
rescue ex rescue ex

View file

@ -82,15 +82,17 @@ def make_client(url : URI, region = nil, force_resolve : Bool = false, &)
end end
end end
def make_configured_http_proxy_client # Fetches a HTTP pool for the specified subdomain of ytimg.com
# This method is only called when configuration for an HTTP proxy are set #
config_proxy = CONFIG.http_proxy.not_nil! # Creates a new one when the specified pool for the subdomain does not exist
def get_ytimg_pool(subdomain)
if pool = YTIMG_POOLS[subdomain]?
return pool
else
LOGGER.info("ytimg_pool: Creating a new HTTP pool for \"https://#{subdomain}.ytimg.com\"")
pool = YoutubeConnectionPool.new(URI.parse("https://#{subdomain}.ytimg.com"), capacity: CONFIG.pool_size)
YTIMG_POOLS[subdomain] = pool
return HTTP::Proxy::Client.new( return pool
config_proxy.host, end
config_proxy.port,
username: config_proxy.user,
password: config_proxy.password,
)
end end