summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamantaz Fox <coding@samantaz.fr>2024-08-07 23:12:27 +0200
committerSamantaz Fox <coding@samantaz.fr>2024-08-07 23:25:35 +0200
commit7798faf23425f11cee77742629ca589a5f33392b (patch)
treec00fe930368ae66df7b3aae8b62312138c8eafdb /src
parentec1bb5db87a40d74203a09ca401d0f70d0ad962d (diff)
downloadinvidious-7798faf23425f11cee77742629ca589a5f33392b.tar.gz
invidious-7798faf23425f11cee77742629ca589a5f33392b.tar.bz2
invidious-7798faf23425f11cee77742629ca589a5f33392b.zip
SigHelper: Make signature server optional and configurable
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr9
-rw-r--r--src/invidious/config.cr4
-rw-r--r--src/invidious/helpers/sig_helper.cr27
-rw-r--r--src/invidious/helpers/signatures.cr16
-rw-r--r--src/invidious/videos.cr6
-rw-r--r--src/invidious/yt_backend/youtube_api.cr4
6 files changed, 39 insertions, 27 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 0c53197d..3804197e 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -153,6 +153,15 @@ Invidious::Database.check_integrity(CONFIG)
{% puts "\nDone checking player dependencies, now compiling Invidious...\n" %}
{% end %}
+# Misc
+
+DECRYPT_FUNCTION =
+ if sig_helper_address = CONFIG.signature_server.presence
+ IV::DecryptFunction.new(sig_helper_address)
+ else
+ nil
+ end
+
# Start jobs
if CONFIG.channel_threads > 0
diff --git a/src/invidious/config.cr b/src/invidious/config.cr
index da911e04..29c39bd6 100644
--- a/src/invidious/config.cr
+++ b/src/invidious/config.cr
@@ -118,6 +118,10 @@ class Config
# Connect to YouTube over 'ipv6', 'ipv4'. Will sometimes resolve fix issues with rate-limiting (see https://github.com/ytdl-org/youtube-dl/issues/21729)
@[YAML::Field(converter: Preferences::FamilyConverter)]
property force_resolve : Socket::Family = Socket::Family::UNSPEC
+
+ # External signature solver server socket (either a path to a UNIX domain socket or "<IP>:<Port>")
+ property signature_server : String? = nil
+
# Port to listen for connections (overridden by command line argument)
property port : Int32 = 3000
# Host to bind (overridden by command line argument)
diff --git a/src/invidious/helpers/sig_helper.cr b/src/invidious/helpers/sig_helper.cr
index 2239858b..13026321 100644
--- a/src/invidious/helpers/sig_helper.cr
+++ b/src/invidious/helpers/sig_helper.cr
@@ -72,8 +72,12 @@ module Invidious::SigHelper
# High-level functions
# ----------------------
- module Client
- extend self
+ class Client
+ @mux : Multiplexor
+
+ def initialize(uri_or_path)
+ @mux = Multiplexor.new(uri_or_path)
+ end
# Forces the server to re-fetch the YouTube player, and extract the necessary
# components from it (nsig function code, sig function code, signature timestamp).
@@ -148,7 +152,7 @@ module Invidious::SigHelper
end
private def send_request(request : Request, &)
- channel = Multiplexor::INSTANCE.send(request)
+ channel = @mux.send(request)
slice = channel.receive
return yield slice
rescue ex
@@ -172,10 +176,8 @@ module Invidious::SigHelper
@conn : Connection
- INSTANCE = new("")
-
- def initialize(url : String)
- @conn = Connection.new(url)
+ def initialize(uri_or_path)
+ @conn = Connection.new(uri_or_path)
listen
end
@@ -275,13 +277,14 @@ module Invidious::SigHelper
{% end %}
def initialize(host_or_path : String)
- if host_or_path.empty?
- host_or_path = "/tmp/inv_sig_helper.sock"
- end
-
case host_or_path
when .starts_with?('/')
- @socket = UNIXSocket.new(host_or_path)
+ # Make sure that the file exists
+ if File.exists?(host_or_path)
+ @socket = UNIXSocket.new(host_or_path)
+ else
+ raise Exception.new("SigHelper: '#{host_or_path}' no such file")
+ end
when .starts_with?("tcp://")
uri = URI.parse(host_or_path)
@socket = TCPSocket.new(uri.host.not_nil!, uri.port.not_nil!)
diff --git a/src/invidious/helpers/signatures.cr b/src/invidious/helpers/signatures.cr
index cf170668..a2abf327 100644
--- a/src/invidious/helpers/signatures.cr
+++ b/src/invidious/helpers/signatures.cr
@@ -1,10 +1,11 @@
require "http/params"
require "./sig_helper"
-struct Invidious::DecryptFunction
+class Invidious::DecryptFunction
@last_update : Time = Time.utc - 42.days
- def initialize
+ def initialize(uri_or_path)
+ @client = SigHelper::Client.new(uri_or_path)
self.check_update
end
@@ -16,19 +17,18 @@ struct Invidious::DecryptFunction
# Get the time when the player was updated, in the event where
# multiple invidious processes are run in parallel.
- player_ts = Invidious::SigHelper::Client.get_player_timestamp
- player_time = Time.unix(player_ts || 0)
+ player_time = Time.unix(@client.get_player_timestamp || 0)
if (now - player_time) > 5.minutes
LOGGER.debug("Signature: Player might be outdated, updating")
- Invidious::SigHelper::Client.force_update
+ @client.force_update
@last_update = Time.utc
end
end
def decrypt_nsig(n : String) : String?
self.check_update
- return SigHelper::Client.decrypt_n_param(n)
+ return @client.decrypt_n_param(n)
rescue ex
LOGGER.debug(ex.message || "Signature: Unknown error")
LOGGER.trace(ex.inspect_with_backtrace)
@@ -37,7 +37,7 @@ struct Invidious::DecryptFunction
def decrypt_signature(str : String) : String?
self.check_update
- return SigHelper::Client.decrypt_sig(str)
+ return @client.decrypt_sig(str)
rescue ex
LOGGER.debug(ex.message || "Signature: Unknown error")
LOGGER.trace(ex.inspect_with_backtrace)
@@ -46,7 +46,7 @@ struct Invidious::DecryptFunction
def get_sts : UInt64?
self.check_update
- return SigHelper::Client.get_signature_timestamp
+ return @client.get_signature_timestamp
rescue ex
LOGGER.debug(ex.message || "Signature: Unknown error")
LOGGER.trace(ex.inspect_with_backtrace)
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index ed172878..8e1e4aac 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -1,5 +1,3 @@
-private DECRYPT_FUNCTION = IV::DecryptFunction.new
-
enum VideoType
Video
Livestream
@@ -108,14 +106,14 @@ struct Video
LOGGER.debug("Videos: Decoding '#{cfr}'")
- unsig = DECRYPT_FUNCTION.decrypt_signature(cfr["s"])
+ unsig = DECRYPT_FUNCTION.try &.decrypt_signature(cfr["s"])
params[sp] = unsig if unsig
else
url = URI.parse(fmt["url"].as_s)
params = url.query_params
end
- n = DECRYPT_FUNCTION.decrypt_nsig(params["n"])
+ n = DECRYPT_FUNCTION.try &.decrypt_nsig(params["n"])
params["n"] = n if n
params["host"] = url.host.not_nil!
diff --git a/src/invidious/yt_backend/youtube_api.cr b/src/invidious/yt_backend/youtube_api.cr
index f4ee35e5..09a5e7f4 100644
--- a/src/invidious/yt_backend/youtube_api.cr
+++ b/src/invidious/yt_backend/youtube_api.cr
@@ -2,8 +2,6 @@
# This file contains youtube API wrappers
#
-private STS_FETCHER = IV::DecryptFunction.new
-
module YoutubeAPI
extend self
@@ -462,7 +460,7 @@ module YoutubeAPI
} of String => String | Int64
if {"WEB", "TVHTML5"}.any? { |s| client_config.name.starts_with? s }
- if sts = STS_FETCHER.get_sts
+ if sts = DECRYPT_FUNCTION.try &.get_sts
playback_ctx["signatureTimestamp"] = sts.to_i64
end
end