mirror of
https://github.com/iv-org/invidious.git
synced 2025-08-13 16:18:29 +00:00
Replace lsquic.cr with invidious-quic-proxy
This commit is contained in:
parent
49d9491fda
commit
a12220ce80
@ -101,6 +101,8 @@ class Config
|
|||||||
property host_binding : String = "0.0.0.0" # Host to bind (overrided by command line argument)
|
property host_binding : String = "0.0.0.0" # Host to bind (overrided by command line argument)
|
||||||
property pool_size : Int32 = 100 # 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 # Pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool of `pool_size`)
|
||||||
property use_quic : Bool = true # Use quic transport for youtube api
|
property use_quic : Bool = true # Use quic transport for youtube api
|
||||||
|
property quic_proxy_address : String = "0.0.0.0" # Address for the QUIC proxy
|
||||||
|
property quic_proxy_port : Int32 = 7192 # Port for the Quic Proxy
|
||||||
|
|
||||||
@[YAML::Field(converter: Preferences::StringToCookies)]
|
@[YAML::Field(converter: Preferences::StringToCookies)]
|
||||||
property cookies : HTTP::Cookies = HTTP::Cookies.new # Saved cookies in "name1=value1; name2=value2..." format
|
property cookies : HTTP::Cookies = HTTP::Cookies.new # Saved cookies in "name1=value1; name2=value2..." format
|
||||||
|
@ -20,7 +20,7 @@ struct YoutubeConnectionPool
|
|||||||
property! url : URI
|
property! url : URI
|
||||||
property! capacity : Int32
|
property! capacity : Int32
|
||||||
property! timeout : Float64
|
property! timeout : Float64
|
||||||
property pool : ConnectionPool(QUIC::Client | HTTP::Client)
|
property pool : ConnectionPool(QuicProxyWrapper | HTTP::Client | QUIC::Client)
|
||||||
|
|
||||||
def initialize(url : URI, @capacity = 5, @timeout = 5.0, use_quic = true)
|
def initialize(url : URI, @capacity = 5, @timeout = 5.0, use_quic = true)
|
||||||
@url = url
|
@url = url
|
||||||
@ -36,11 +36,7 @@ struct YoutubeConnectionPool
|
|||||||
begin
|
begin
|
||||||
response = yield conn
|
response = yield conn
|
||||||
rescue ex
|
rescue ex
|
||||||
conn.close
|
conn = QuicProxyWrapper.new(url)
|
||||||
conn = QUIC::Client.new(url)
|
|
||||||
conn.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::INET
|
|
||||||
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"
|
|
||||||
response = yield conn
|
response = yield conn
|
||||||
ensure
|
ensure
|
||||||
pool.checkin(conn)
|
pool.checkin(conn)
|
||||||
@ -51,20 +47,145 @@ struct YoutubeConnectionPool
|
|||||||
end
|
end
|
||||||
|
|
||||||
private def build_pool(use_quic)
|
private def build_pool(use_quic)
|
||||||
ConnectionPool(QUIC::Client | HTTP::Client).new(capacity: capacity, timeout: timeout) do
|
ConnectionPool(QuicProxyWrapper | HTTP::Client | QUIC::Client).new(capacity: capacity, timeout: timeout) do
|
||||||
if use_quic
|
if use_quic
|
||||||
conn = QUIC::Client.new(url)
|
conn = QuicProxyWrapper.new(URI.parse("http://#{CONFIG.quic_proxy_address}:#{CONFIG.quic_proxy_port}"))
|
||||||
else
|
else
|
||||||
conn = HTTP::Client.new(url)
|
conn = HTTP::Client.new(url)
|
||||||
|
conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
|
||||||
end
|
end
|
||||||
conn.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::INET
|
conn.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::INET
|
||||||
conn.family = Socket::Family::INET if conn.family == Socket::Family::UNSPEC
|
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"
|
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class QuicProxyWrapper
|
||||||
|
property yt_headers : Hash(String, String)
|
||||||
|
def initialize(url : URI, family : Socket::Family = Socket::Family::UNSPEC)
|
||||||
|
@conn = HTTP::Client.new(url)
|
||||||
|
@family = family
|
||||||
|
header_retreival = HackyHeaderRetrevialClass.new
|
||||||
|
add_yt_headers(header_retreival)
|
||||||
|
|
||||||
|
@yt_headers = header_retreival.headers
|
||||||
|
# Scans through yt_headers and makes sure that all values are strings.
|
||||||
|
@yt_headers.each do |k,v|
|
||||||
|
if v.is_a? Array
|
||||||
|
@yt_headers[k] = v[0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def family=(value)0
|
||||||
|
end
|
||||||
|
|
||||||
|
def family
|
||||||
|
return @family
|
||||||
|
end
|
||||||
|
|
||||||
|
def close
|
||||||
|
@conn.close
|
||||||
|
end
|
||||||
|
|
||||||
|
{% for method in %w(get post head) %}
|
||||||
|
def {{method.id}}(url, headers, body : String)
|
||||||
|
headers = convert_headers(headers)
|
||||||
|
headers.merge!(@yt_headers)
|
||||||
|
data = {"method" => {{method.upcase}}, "url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers"=>headers.to_h, "data" => body}.to_json
|
||||||
|
|
||||||
|
return @conn.post("/", body: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def {{method.id}}(url, headers, body : String)
|
||||||
|
headers = convert_headers(headers)
|
||||||
|
headers.merge!(@yt_headers)
|
||||||
|
data = {"method" => {{method.upcase}}, "url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers"=>headers.to_h, "data" => body}.to_json
|
||||||
|
|
||||||
|
@conn.post("/", body: data) do |response|
|
||||||
|
yield response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def {{method.id}}(url, headers)
|
||||||
|
headers = convert_headers(headers)
|
||||||
|
headers.merge!(@yt_headers)
|
||||||
|
data = {"method" => {{method.upcase}}, "url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers"=>headers.to_h}.to_json
|
||||||
|
|
||||||
|
return @conn.post("/", body: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def {{method.id}}(url, headers)
|
||||||
|
headers = convert_headers(headers)
|
||||||
|
headers.merge!(@yt_headers)
|
||||||
|
data = {"method" => {{method.upcase}}, "url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers"=>headers.to_h}.to_json
|
||||||
|
|
||||||
|
results = @conn.post("/", body: data)
|
||||||
|
@conn.post("/", body: data) do |response|
|
||||||
|
yield response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def {{method.id}}(url)
|
||||||
|
data = {"method" => {{method.upcase}},
|
||||||
|
"url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers" => @yt_headers}.to_json
|
||||||
|
return @conn.post("/", body: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def {{method.id}}(url)
|
||||||
|
data = {"method" => {{method.upcase}},
|
||||||
|
"url" => "#{YT_URL.to_s}#{url}", "headers" => @yt_headers}.to_json
|
||||||
|
@conn.post("/", body: data) do |response|
|
||||||
|
yield response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
def post(url, headers, form)
|
||||||
|
headers = convert_headers(headers)
|
||||||
|
headers.merge!(@yt_headers)
|
||||||
|
data = {"method" => "POST", "url" => "#{YT_URL.to_s}#{url}",
|
||||||
|
"headers"=>headers.to_h, "data" => form}.to_json
|
||||||
|
|
||||||
|
return @conn.post("/", body: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_headers(headers)
|
||||||
|
new_headers_dict = {} of String => String
|
||||||
|
headers.each do |k, v|
|
||||||
|
if v.is_a? Array
|
||||||
|
new_headers_dict[k] = v[0]
|
||||||
|
else
|
||||||
|
new_headers_dict[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return new_headers_dict
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# We're just using this to retreive the headers from add_yt_headers
|
||||||
|
class HackyHeaderRetrevialClass
|
||||||
|
def initialize()
|
||||||
|
@headers_dict = {} of String => String
|
||||||
|
end
|
||||||
|
|
||||||
|
def headers()
|
||||||
|
return @headers_dict
|
||||||
|
end
|
||||||
|
|
||||||
|
def resource()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# See http://www.evanmiller.org/how-not-to-sort-by-average-rating.html
|
# See http://www.evanmiller.org/how-not-to-sort-by-average-rating.html
|
||||||
def ci_lower_bound(pos, n)
|
def ci_lower_bound(pos, n)
|
||||||
if n == 0
|
if n == 0
|
||||||
|
Loading…
Reference in New Issue
Block a user