summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsyeopite <syeopite@syeopite.dev>2023-08-25 16:08:02 -0700
committersyeopite <syeopite@syeopite.dev>2024-04-28 19:43:17 -0700
commiteb8fcc9e88bf71694e7d9e40600ef3fd334bc46e (patch)
tree6dc54d675129b88a2fc2c88f50f06e2d0f837252
parenteda7444ca46dbc3941205316baba8030fe0b2989 (diff)
downloadinvidious-eb8fcc9e88bf71694e7d9e40600ef3fd334bc46e.tar.gz
invidious-eb8fcc9e88bf71694e7d9e40600ef3fd334bc46e.tar.bz2
invidious-eb8fcc9e88bf71694e7d9e40600ef3fd334bc46e.zip
Add support for using HTTP proxies
-rw-r--r--config/config.example.yml11
-rw-r--r--shard.lock10
-rw-r--r--shard.yml3
-rw-r--r--src/invidious.cr1
-rw-r--r--src/invidious/config.cr11
-rw-r--r--src/invidious/yt_backend/connection_pool.cr18
6 files changed, 51 insertions, 3 deletions
diff --git a/config/config.example.yml b/config/config.example.yml
index 38085a20..9fdc4eda 100644
--- a/config/config.example.yml
+++ b/config/config.example.yml
@@ -160,6 +160,17 @@ https_only: false
##
#force_resolve:
+##
+## Configuration for using a HTTP proxy
+##
+## If unset, then no HTTP proxy will be used.
+##
+http_proxy:
+ user:
+ password:
+ host:
+ port:
+
##
## Use Innertube's transcripts API instead of timedtext for closed captions
diff --git a/shard.lock b/shard.lock
index efb60a59..85928c47 100644
--- a/shard.lock
+++ b/shard.lock
@@ -6,11 +6,11 @@ shards:
athena-negotiation:
git: https://github.com/athena-framework/negotiation.git
- version: 0.1.1
+ version: 0.1.3
backtracer:
git: https://github.com/sija/backtracer.cr.git
- version: 1.2.1
+ version: 1.2.2
db:
git: https://github.com/crystal-lang/crystal-db.git
@@ -20,6 +20,10 @@ shards:
git: https://github.com/crystal-loot/exception_page.git
version: 0.2.2
+ http_proxy:
+ git: https://github.com/mamantoha/http_proxy.git
+ version: 0.10.1
+
kemal:
git: https://github.com/kemalcr/kemal.git
version: 1.1.2
@@ -42,7 +46,7 @@ shards:
spectator:
git: https://github.com/icy-arctic-fox/spectator.git
- version: 0.10.4
+ version: 0.10.6
sqlite3:
git: https://github.com/crystal-lang/crystal-sqlite3.git
diff --git a/shard.yml b/shard.yml
index be06a7df..ddd510d4 100644
--- a/shard.yml
+++ b/shard.yml
@@ -28,6 +28,9 @@ dependencies:
athena-negotiation:
github: athena-framework/negotiation
version: ~> 0.1.1
+ http_proxy:
+ github: mamantoha/http_proxy
+ version: ~> 0.10.1
development_dependencies:
spectator:
diff --git a/src/invidious.cr b/src/invidious.cr
index e0bd0101..d4114386 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -23,6 +23,7 @@ require "kilt"
require "./ext/kemal_content_for.cr"
require "./ext/kemal_static_file_handler.cr"
+require "http_proxy"
require "athena-negotiation"
require "openssl/hmac"
require "option_parser"
diff --git a/src/invidious/config.cr b/src/invidious/config.cr
index 09c2168b..e12054d0 100644
--- a/src/invidious/config.cr
+++ b/src/invidious/config.cr
@@ -54,6 +54,15 @@ struct ConfigPreferences
end
end
+struct HTTPProxyConfig
+ include YAML::Serializable
+
+ property user : String
+ property password : String
+ property host : String
+ property port : Int32
+end
+
class Config
include YAML::Serializable
@@ -126,6 +135,8 @@ 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
+ # HTTP Proxy configuration
+ property http_proxy : HTTPProxyConfig? = nil
# Use Innertube's transcripts API instead of timedtext for closed captions
property use_innertube_for_captions : Bool = false
diff --git a/src/invidious/yt_backend/connection_pool.cr b/src/invidious/yt_backend/connection_pool.cr
index d3dbcc0e..0e4d8aff 100644
--- a/src/invidious/yt_backend/connection_pool.cr
+++ b/src/invidious/yt_backend/connection_pool.cr
@@ -26,12 +26,14 @@ struct YoutubeConnectionPool
def client(&block)
conn = pool.checkout
+ conn.proxy = make_configured_http_proxy_client() if CONFIG.http_proxy
begin
response = yield conn
rescue ex
conn.close
conn = HTTP::Client.new(url)
+ conn.proxy = make_configured_http_proxy_client() if CONFIG.http_proxy
conn.family = CONFIG.force_resolve
conn.family = Socket::Family::INET if conn.family == Socket::Family::UNSPEC
conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
@@ -46,6 +48,7 @@ struct YoutubeConnectionPool
private def build_pool
DB::Pool(HTTP::Client).new(initial_pool_size: 0, max_pool_size: capacity, max_idle_pool_size: capacity, checkout_timeout: timeout) do
conn = HTTP::Client.new(url)
+ conn.proxy = make_configured_http_proxy_client() if CONFIG.http_proxy
conn.family = CONFIG.force_resolve
conn.family = Socket::Family::INET if conn.family == Socket::Family::UNSPEC
conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
@@ -66,6 +69,8 @@ def make_client(url : URI, region = nil, force_resolve : Bool = false)
client.read_timeout = 10.seconds
client.connect_timeout = 10.seconds
+ client.proxy = make_configured_http_proxy_client() if CONFIG.http_proxy
+
return client
end
@@ -77,3 +82,16 @@ def make_client(url : URI, region = nil, force_resolve : Bool = false, &block)
client.close
end
end
+
+def make_configured_http_proxy_client
+ # This method is only called when configuration for an HTTP proxy are set
+ config_proxy = CONFIG.http_proxy.not_nil!
+
+ return HTTP::Proxy::Client.new(
+ config_proxy.host,
+ config_proxy.port,
+
+ username: config_proxy.user,
+ password: config_proxy.password,
+ )
+end