diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 9fc58409..3856a454 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -126,8 +126,10 @@ class Config property host_binding : String = "0.0.0.0" # Pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool of `pool_size`) property pool_size : Int32 = 100 + # Use quic transport for youtube api - property use_quic : Bool = false + # Note: The getter function is defined below to take into account the compile-time flag + setter use_quic : Bool = false # Saved cookies in "name1=value1; name2=value2..." format @[YAML::Field(converter: Preferences::StringToCookies)] @@ -155,6 +157,16 @@ class Config end end + # Return whether QUIC is enabled or not. + # Takes into account compile-time flag AND runtime config. + def use_quic : Bool + {% if flag?(:disable_quic) %} + return false + {% else %} + return @use_quic + {% end %} + end + def self.load # Load config from file or YAML string env var env_config_file = "INVIDIOUS_CONFIG_FILE" diff --git a/src/invidious/routes/images.cr b/src/invidious/routes/images.cr index 594a7869..d6f6d3db 100644 --- a/src/invidious/routes/images.cr +++ b/src/invidious/routes/images.cr @@ -3,17 +3,8 @@ module Invidious::Routes::Images def self.ggpht(env) url = env.request.path.lchop("/ggpht") - headers = ( - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - HTTP::Headers{":authority" => "yt3.ggpht.com"} - else - HTTP::Headers.new - end - {% else %} - HTTP::Headers.new - {% end %} - ) + headers = HTTP::Headers.new + headers[":authority"] = "yt3.ggpht.com" if CONFIG.use_quic REQUEST_HEADERS_WHITELIST.each do |header| if env.request.headers[header]? @@ -42,22 +33,16 @@ module Invidious::Routes::Images } begin - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - YT_POOL.client &.get(url, headers) do |resp| - return request_proc.call(resp) - end - else - HTTP::Client.get("https://yt3.ggpht.com#{url}") do |resp| - return request_proc.call(resp) - end + if CONFIG.use_quic + YT_POOL.client &.get(url, headers) do |resp| + return request_proc.call(resp) end - {% else %} + else # This can likely be optimized into a (small) pool sometime in the future. HTTP::Client.get("https://yt3.ggpht.com#{url}") do |resp| return request_proc.call(resp) end - {% end %} + end rescue ex end end @@ -77,10 +62,7 @@ module Invidious::Routes::Images url = "/sb/#{id}/#{storyboard}/#{index}?#{env.params.query}" headers = HTTP::Headers.new - - {% unless flag?(:disable_quic) %} - headers[":authority"] = "#{authority}.ytimg.com" - {% end %} + headers[":authority"] = "#{authority}.ytimg.com" if CONFIG.use_quic REQUEST_HEADERS_WHITELIST.each do |header| if env.request.headers[header]? @@ -107,22 +89,16 @@ module Invidious::Routes::Images } begin - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - YT_POOL.client &.get(url, headers) do |resp| - return request_proc.call(resp) - end - else - HTTP::Client.get("https://#{authority}.ytimg.com#{url}") do |resp| - return request_proc.call(resp) - end + if CONFIG.use_quic + YT_POOL.client &.get(url, headers) do |resp| + return request_proc.call(resp) end - {% else %} + else # This can likely be optimized into a (small) pool sometime in the future. HTTP::Client.get("https://#{authority}.ytimg.com#{url}") do |resp| return request_proc.call(resp) end - {% end %} + end rescue ex end end @@ -133,17 +109,8 @@ module Invidious::Routes::Images name = env.params.url["name"] url = env.request.resource - headers = ( - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - HTTP::Headers{":authority" => "i9.ytimg.com"} - else - HTTP::Headers.new - end - {% else %} - HTTP::Headers.new - {% end %} - ) + headers = HTTP::Headers.new + headers[":authority"] = "i9.ytimg.com" if CONFIG.use_quic REQUEST_HEADERS_WHITELIST.each do |header| if env.request.headers[header]? @@ -169,22 +136,16 @@ module Invidious::Routes::Images } begin - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - YT_POOL.client &.get(url, headers) do |resp| - return request_proc.call(resp) - end - else - HTTP::Client.get("https://i9.ytimg.com#{url}") do |resp| - return request_proc.call(resp) - end + if CONFIG.use_quic + YT_POOL.client &.get(url, headers) do |resp| + return request_proc.call(resp) end - {% else %} + else # This can likely be optimized into a (small) pool sometime in the future. HTTP::Client.get("https://i9.ytimg.com#{url}") do |resp| return request_proc.call(resp) end - {% end %} + end rescue ex end end @@ -223,41 +184,26 @@ module Invidious::Routes::Images id = env.params.url["id"] name = env.params.url["name"] - headers = ( - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - HTTP::Headers{":authority" => "i.ytimg.com"} - else - HTTP::Headers.new - end - {% else %} - HTTP::Headers.new - {% end %} - ) + headers = HTTP::Headers.new + headers[":authority"] = "i.ytimg.com" if CONFIG.use_quic if name == "maxres.jpg" build_thumbnails(id).each do |thumb| thumbnail_resource_path = "/vi/#{id}/#{thumb[:url]}.jpg" + # Logic here is short enough that manually typing them out should be fine. - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - if YT_POOL.client &.head(thumbnail_resource_path, headers).status_code == 200 - name = thumb[:url] + ".jpg" - break - end - else - if HTTP::Client.head("https://i.ytimg.com#{thumbnail_resource_path}").status_code == 200 - name = thumb[:url] + ".jpg" - break - end + if CONFIG.use_quic + if YT_POOL.client &.head(thumbnail_resource_path, headers).status_code == 200 + name = thumb[:url] + ".jpg" + break end - {% else %} + else # This can likely be optimized into a (small) pool sometime in the future. if HTTP::Client.head("https://i.ytimg.com#{thumbnail_resource_path}").status_code == 200 name = thumb[:url] + ".jpg" break end - {% end %} + end end end @@ -287,22 +233,16 @@ module Invidious::Routes::Images } begin - {% unless flag?(:disable_quic) %} - if CONFIG.use_quic - YT_POOL.client &.get(url, headers) do |resp| - return request_proc.call(resp) - end - else - HTTP::Client.get("https://i.ytimg.com#{url}") do |resp| - return request_proc.call(resp) - end + if CONFIG.use_quic + YT_POOL.client &.get(url, headers) do |resp| + return request_proc.call(resp) end - {% else %} + else # This can likely be optimized into a (small) pool sometime in the future. HTTP::Client.get("https://i.ytimg.com#{url}") do |resp| return request_proc.call(resp) end - {% end %} + end rescue ex end end diff --git a/src/invidious/yt_backend/connection_pool.cr b/src/invidious/yt_backend/connection_pool.cr index 46e5bf85..8d727129 100644 --- a/src/invidious/yt_backend/connection_pool.cr +++ b/src/invidious/yt_backend/connection_pool.cr @@ -63,11 +63,7 @@ struct YoutubeConnectionPool DB::Pool(HTTPClientType).new(initial_pool_size: 0, max_pool_size: capacity, max_idle_pool_size: capacity, checkout_timeout: timeout) do conn = nil # Declare {% unless flag?(:disable_quic) %} - if use_quic - conn = QUIC::Client.new(url) - else - conn = HTTP::Client.new(url) - end + conn = CONFIG.use_quic ? QUIC::Client.new(url) : HTTP::Client.new(url) {% else %} conn = HTTP::Client.new(url) {% end %} diff --git a/src/invidious/yt_backend/youtube_api.cr b/src/invidious/yt_backend/youtube_api.cr index 91a9332c..7a2907be 100644 --- a/src/invidious/yt_backend/youtube_api.cr +++ b/src/invidious/yt_backend/youtube_api.cr @@ -593,7 +593,7 @@ module YoutubeAPI LOGGER.trace("YoutubeAPI: POST data: #{data}") # Send the POST request - if {{ !flag?(:disable_quic) }} && CONFIG.use_quic + if CONFIG.use_quic # Using QUIC client body = YT_POOL.client(client_config.proxy_region, &.post(url, headers: headers, body: data.to_json)