summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr10
-rw-r--r--src/invidious/helpers/jobs.cr54
-rw-r--r--src/invidious/helpers/utils.cr12
3 files changed, 68 insertions, 8 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 147fe935..a4f20bc4 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -87,6 +87,7 @@ LOCALES = {
"nb_NO" => load_locale("nb_NO"),
"nl" => load_locale("nl"),
"pl" => load_locale("pl"),
+ "ro" => load_locale("ro"),
"ru" => load_locale("ru"),
"tr" => load_locale("tr"),
"uk" => load_locale("uk"),
@@ -3852,7 +3853,7 @@ get "/api/v1/captions/:id" do |env|
caption = caption[0]
end
- url = "#{caption.baseUrl}&tlang=#{tlang}"
+ url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path
# Auto-generated captions often have cues that aren't aligned properly with the video,
# as well as some other markup that makes it cumbersome, so we try to fix that here
@@ -4523,9 +4524,10 @@ get "/api/v1/search/suggestions" do |env|
query ||= ""
begin
- response = QUIC::Client.get(
- "https://suggestqueries.google.com/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback"
- ).body
+ client = QUIC::Client.new("suggestqueries.google.com")
+ client.family = CONFIG.force_resolve || Socket::Family::INET
+ client.family = Socket::Family::INET if client.family == Socket::Family::UNSPEC
+ response = client.get("/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback").body
body = response[35..-2]
body = JSON.parse(body).as_a
diff --git a/src/invidious/helpers/jobs.cr b/src/invidious/helpers/jobs.cr
index 5838b5b3..f368d6df 100644
--- a/src/invidious/helpers/jobs.cr
+++ b/src/invidious/helpers/jobs.cr
@@ -290,6 +290,60 @@ def bypass_captcha(captcha_key, logger)
response = YT_POOL.client &.post("/das_captcha", headers, form: inputs)
yield response.cookies.select { |cookie| cookie.name != "PREF" }
+ elsif response.headers["Location"]?.try &.includes?("/sorry/index")
+ location = response.headers["Location"].try { |u| URI.parse(u) }
+ client = QUIC::Client.new(location.host.not_nil!)
+ response = client.get(location.full_path)
+
+ html = XML.parse_html(response.body)
+ form = html.xpath_node(%(//form[@action="index"])).not_nil!
+ site_key = form.xpath_node(%(.//div[@class="g-recaptcha"])).try &.["data-sitekey"]
+
+ inputs = {} of String => String
+ form.xpath_nodes(%(.//input[@name])).map do |node|
+ inputs[node["name"]] = node["value"]
+ end
+
+ response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/createTask", body: {
+ "clientKey" => CONFIG.captcha_key,
+ "task" => {
+ "type" => "NoCaptchaTaskProxyless",
+ "websiteURL" => location.to_s,
+ "websiteKey" => site_key,
+ },
+ }.to_json).body)
+
+ if response["error"]?
+ raise response["error"].as_s
+ end
+
+ task_id = response["taskId"].as_i
+
+ loop do
+ sleep 10.seconds
+
+ response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/getTaskResult", body: {
+ "clientKey" => CONFIG.captcha_key,
+ "taskId" => task_id,
+ }.to_json).body)
+
+ if response["status"]?.try &.== "ready"
+ break
+ elsif response["errorId"]?.try &.as_i != 0
+ raise response["errorDescription"].as_s
+ end
+ end
+
+ inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
+ client.close
+ client = QUIC::Client.new("www.google.com")
+ response = client.post(location.full_path, form: inputs)
+ headers = HTTP::Headers{
+ "Cookie" => URI.parse(response.headers["location"]).query_params["google_abuse"].split(";")[0],
+ }
+ cookies = HTTP::Cookies.from_headers(headers)
+
+ yield cookies
end
rescue ex
logger.puts("Exception: #{ex.message}")
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index 53c18dd5..6fcfa8d2 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -31,8 +31,10 @@ struct QUICPool
begin
response = yield conn
rescue ex
- conn.destroy_engine
+ conn.close
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
ensure
@@ -45,9 +47,11 @@ struct QUICPool
private def build_pool
ConnectionPool(QUIC::Client).new(capacity: capacity, timeout: timeout) do
- client = QUIC::Client.new(url)
- client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- client
+ 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"
+ conn
end
end
end