mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-11-04 06:31:57 +00:00 
			
		
		
		
	Make geo-bypass more robust
This commit is contained in:
		@@ -1874,27 +1874,30 @@ get "/api/v1/comments/:id" do |env|
 | 
			
		||||
 | 
			
		||||
      proxies.each do |region, list|
 | 
			
		||||
        spawn do
 | 
			
		||||
          begin
 | 
			
		||||
            proxy_client = HTTPClient.new(YT_URL)
 | 
			
		||||
            proxy_client.read_timeout = 10.seconds
 | 
			
		||||
            proxy_client.connect_timeout = 10.seconds
 | 
			
		||||
          list.each do |proxy|
 | 
			
		||||
            begin
 | 
			
		||||
              proxy_client = HTTPClient.new(YT_URL)
 | 
			
		||||
              proxy_client.read_timeout = 10.seconds
 | 
			
		||||
              proxy_client.connect_timeout = 10.seconds
 | 
			
		||||
 | 
			
		||||
            proxy = list.sample(1)[0]
 | 
			
		||||
            proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
            proxy_client.set_proxy(proxy)
 | 
			
		||||
              proxy = list.sample(1)[0]
 | 
			
		||||
              proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
              proxy_client.set_proxy(proxy)
 | 
			
		||||
 | 
			
		||||
            proxy_html = proxy_client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
            proxy_headers = HTTP::Headers.new
 | 
			
		||||
            proxy_headers["cookie"] = proxy_html.cookies.add_request_headers(headers)["cookie"]
 | 
			
		||||
            proxy_html = proxy_html.body
 | 
			
		||||
              proxy_html = proxy_client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
              proxy_headers = HTTP::Headers.new
 | 
			
		||||
              proxy_headers["cookie"] = proxy_html.cookies.add_request_headers(headers)["cookie"]
 | 
			
		||||
              proxy_html = proxy_html.body
 | 
			
		||||
 | 
			
		||||
            if proxy_html.match(/<meta itemprop="regionsAllowed" content="">/)
 | 
			
		||||
              bypass_channel.send(nil)
 | 
			
		||||
            else
 | 
			
		||||
              bypass_channel.send({proxy_html, proxy_client, proxy_headers})
 | 
			
		||||
              if proxy_html.match(/<meta itemprop="regionsAllowed" content="">/)
 | 
			
		||||
                bypass_channel.send(nil)
 | 
			
		||||
              else
 | 
			
		||||
                bypass_channel.send({proxy_html, proxy_client, proxy_headers})
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
              break
 | 
			
		||||
            rescue ex
 | 
			
		||||
            end
 | 
			
		||||
          rescue ex
 | 
			
		||||
            bypass_channel.send(nil)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
@@ -3227,34 +3230,39 @@ get "/videoplayback" do |env|
 | 
			
		||||
  host = "https://r#{fvip}---#{mn}.googlevideo.com"
 | 
			
		||||
  url = "/videoplayback?#{query_params.to_s}"
 | 
			
		||||
 | 
			
		||||
  client = make_client(URI.parse(host))
 | 
			
		||||
  response = client.head(url)
 | 
			
		||||
  if query_params["region"]?
 | 
			
		||||
    client = make_client(URI.parse(host))
 | 
			
		||||
    response = HTTP::Client::Response.new(status_code: 403)
 | 
			
		||||
 | 
			
		||||
  if response.status_code == 403
 | 
			
		||||
    ip = query_params["ip"]
 | 
			
		||||
    proxy = proxies.values.flatten.select { |proxy| proxy[:ip] == ip }
 | 
			
		||||
    if proxy.empty?
 | 
			
		||||
    if !proxies[query_params["region"]]?
 | 
			
		||||
      halt env, status_code: 403
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    proxy = proxy[0]
 | 
			
		||||
    # Try to find proxy in same region
 | 
			
		||||
    proxy = proxies.select { |region, list| list.includes? proxy }.values[0].sample(1)[0]
 | 
			
		||||
    if proxy.empty?
 | 
			
		||||
      halt env, status_code: 403
 | 
			
		||||
    proxies[query_params["region"]].each do |proxy|
 | 
			
		||||
      begin
 | 
			
		||||
        client = HTTPClient.new(URI.parse(host))
 | 
			
		||||
        client.read_timeout = 10.seconds
 | 
			
		||||
        client.connect_timeout = 10.seconds
 | 
			
		||||
 | 
			
		||||
        proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
        client.set_proxy(proxy)
 | 
			
		||||
 | 
			
		||||
        response = client.head(url)
 | 
			
		||||
        if response.status_code == 200
 | 
			
		||||
          # For whatever reason the proxy needs to be set again
 | 
			
		||||
          client.set_proxy(proxy)
 | 
			
		||||
          break
 | 
			
		||||
        end
 | 
			
		||||
      rescue ex
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    client = HTTPClient.new(URI.parse(host))
 | 
			
		||||
    client.read_timeout = 10.seconds
 | 
			
		||||
    client.connect_timeout = 10.seconds
 | 
			
		||||
 | 
			
		||||
    proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
    client.set_proxy(proxy)
 | 
			
		||||
 | 
			
		||||
  else
 | 
			
		||||
    client = make_client(URI.parse(host))
 | 
			
		||||
    response = client.head(url)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
    # For whatever reason the proxy needs to be set again
 | 
			
		||||
    client.set_proxy(proxy)
 | 
			
		||||
  if response.status_code != 200
 | 
			
		||||
    halt env, status_code: 403
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  if response.headers["Location"]?
 | 
			
		||||
 
 | 
			
		||||
@@ -273,6 +273,12 @@ class Video
 | 
			
		||||
    streams.each { |s| s.add("label", "#{s["quality"]} - #{s["type"].split(";")[0].split("/")[1]}") }
 | 
			
		||||
    streams = streams.uniq { |s| s["label"] }
 | 
			
		||||
 | 
			
		||||
    if self.info["region"]?
 | 
			
		||||
      streams.each do |fmt|
 | 
			
		||||
        fmt["url"] += "®ion=" + self.info["region"]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if streams[0]? && streams[0]["s"]?
 | 
			
		||||
      streams.each do |fmt|
 | 
			
		||||
        fmt["url"] += "&signature=" + decrypt_signature(fmt["s"], decrypt_function)
 | 
			
		||||
@@ -362,6 +368,12 @@ class Video
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if self.info["region"]?
 | 
			
		||||
      adaptive_fmts.each do |fmt|
 | 
			
		||||
        fmt["url"] += "®ion=" + self.info["region"]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if adaptive_fmts[0]? && adaptive_fmts[0]["s"]?
 | 
			
		||||
      adaptive_fmts.each do |fmt|
 | 
			
		||||
        fmt["url"] += "&signature=" + decrypt_signature(fmt["s"], decrypt_function)
 | 
			
		||||
@@ -527,47 +539,56 @@ def fetch_video(id, proxies)
 | 
			
		||||
  info = info_channel.receive
 | 
			
		||||
 | 
			
		||||
  if info["reason"]? && info["reason"].includes? "your country"
 | 
			
		||||
    bypass_channel = Channel({HTTP::Params | Nil, XML::Node | Nil}).new
 | 
			
		||||
    bypass_channel = Channel(HTTPProxy | Nil).new
 | 
			
		||||
 | 
			
		||||
    proxies.each do |region, list|
 | 
			
		||||
      spawn do
 | 
			
		||||
        begin
 | 
			
		||||
          client = HTTPClient.new(YT_URL)
 | 
			
		||||
          client.read_timeout = 10.seconds
 | 
			
		||||
          client.connect_timeout = 10.seconds
 | 
			
		||||
        list.each do |proxy|
 | 
			
		||||
          begin
 | 
			
		||||
            client = HTTPClient.new(YT_URL)
 | 
			
		||||
            client.read_timeout = 10.seconds
 | 
			
		||||
            client.connect_timeout = 10.seconds
 | 
			
		||||
 | 
			
		||||
          proxy = list.sample(1)[0]
 | 
			
		||||
          proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
          client.set_proxy(proxy)
 | 
			
		||||
            proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
 | 
			
		||||
            client.set_proxy(proxy)
 | 
			
		||||
 | 
			
		||||
          proxy_info = client.get("/get_video_info?video_id=#{id}&el=detailpage&ps=default&eurl=&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
          proxy_info = HTTP::Params.parse(proxy_info.body)
 | 
			
		||||
            response = client.head("/get_video_info?video_id=#{id}&el=detailpage&ps=default&eurl=&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
            if response.status_code == 200
 | 
			
		||||
              bypass_channel.send(proxy)
 | 
			
		||||
            else
 | 
			
		||||
              bypass_channel.send(nil)
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
          if proxy_info["reason"]?
 | 
			
		||||
            proxy_info = client.get("/get_video_info?video_id=#{id}&ps=default&eurl=&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
            proxy_info = HTTP::Params.parse(proxy_info.body)
 | 
			
		||||
            break
 | 
			
		||||
          rescue ex
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          if !proxy_info["reason"]?
 | 
			
		||||
            proxy_html = client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
            proxy_html = XML.parse_html(proxy_html.body)
 | 
			
		||||
 | 
			
		||||
            bypass_channel.send({proxy_info, proxy_html})
 | 
			
		||||
          else
 | 
			
		||||
            bypass_channel.send({nil, nil})
 | 
			
		||||
          end
 | 
			
		||||
        rescue ex
 | 
			
		||||
          bypass_channel.send({nil, nil})
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    proxies.size.times do
 | 
			
		||||
      response = bypass_channel.receive
 | 
			
		||||
      if response[0] || response[1]
 | 
			
		||||
        info = response[0].not_nil!
 | 
			
		||||
        html = response[1].not_nil!
 | 
			
		||||
        break
 | 
			
		||||
      proxy = bypass_channel.receive
 | 
			
		||||
      if proxy
 | 
			
		||||
        client = HTTPClient.new(YT_URL)
 | 
			
		||||
        client.read_timeout = 10.seconds
 | 
			
		||||
        client.connect_timeout = 10.seconds
 | 
			
		||||
        client.set_proxy(proxy)
 | 
			
		||||
 | 
			
		||||
        proxy = {ip: proxy.proxy_host, port: proxy.proxy_port}
 | 
			
		||||
        region = proxies.select { |region, list| list.includes? proxy }.keys[0]
 | 
			
		||||
 | 
			
		||||
        html = client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
        html = XML.parse_html(html.body)
 | 
			
		||||
 | 
			
		||||
        info = client.get("/get_video_info?video_id=#{id}&el=detailpage&ps=default&eurl=&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
        info = HTTP::Params.parse(info.body)
 | 
			
		||||
 | 
			
		||||
        if info["reason"]?
 | 
			
		||||
          info = client.get("/get_video_info?video_id=#{id}&ps=default&eurl=&gl=US&hl=en&disable_polymer=1")
 | 
			
		||||
          info = HTTP::Params.parse(info.body)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        info["region"] = region
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user