From d46b26e3bc87fbbdfa9550820410041b861bb393 Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Mon, 18 Nov 2019 17:28:32 -0500 Subject: [PATCH] Use QUIC for connections to YouTube --- docker/Dockerfile | 13 +- shard.yml | 3 + src/invidious.cr | 10 +- src/invidious/helpers/jobs.cr | 2 +- src/invidious/helpers/proxy.cr | 15 +- src/invidious/helpers/utils.cr | 1632 +------------------------------- 6 files changed, 73 insertions(+), 1602 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index f6e99ca9c..0defb92b9 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,15 +1,24 @@ FROM alpine:edge RUN apk add --no-cache crystal shards libc-dev \ - yaml-dev libxml2-dev sqlite-dev zlib-dev openssl-dev + yaml-dev libxml2-dev sqlite-dev zlib-dev curl && \ + curl -Lo /etc/apk/keys/omarroth.rsa.pub https://github.com/omarroth/boringssl-alpine/releases/download/1.1.0-r0/omarroth.rsa.pub && \ + curl -Lo boringssl-dev.apk https://github.com/omarroth/boringssl-alpine/releases/download/1.1.0-r0/boringssl-dev-1.1.0-r0.apk && \ + curl -Lo lsquic.apk https://github.com/omarroth/lsquic-alpine/releases/download/2.6.3-r0/lsquic-2.6.3-r0.apk && \ + apk update && \ + apk add boringssl-dev.apk lsquic.apk && \ + rm -rf /var/cache/apk/* boringssl-dev.apk lsquic.apk WORKDIR /invidious COPY ./shard.yml ./shard.yml RUN shards update && shards install +RUN cp /usr/lib/libcrypto.a ./lib/lsquic/src/lsquic/ext/libcrypto.a && \ + cp /usr/lib/libssl.a ./lib/lsquic/src/lsquic/ext/libssl.a && \ + cp /usr/lib/liblsquic.a ./lib/lsquic/src/lsquic/ext/liblsquic.a COPY ./src/ ./src/ # TODO: .git folder is required for building – this is destructive. # See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION. COPY ./.git/ ./.git/ RUN crystal build --release --warnings all --error-on-warnings \ -# TODO: Remove next line, see https://github.com/crystal-lang/crystal/issues/7946 + # TODO: Remove next line, see https://github.com/crystal-lang/crystal/issues/7946 -Dmusl \ ./src/invidious.cr diff --git a/shard.yml b/shard.yml index 730ba261e..8623eed9c 100644 --- a/shard.yml +++ b/shard.yml @@ -24,6 +24,9 @@ dependencies: protodec: github: omarroth/protodec version: ~> 0.1.2 + lsquic: + github: omarroth/lsquic.cr + version: ~> 0.1.3 crystal: 0.31.1 diff --git a/src/invidious.cr b/src/invidious.cr index 94ea1d92c..a766a11ca 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -94,7 +94,7 @@ LOCALES = { "zh-TW" => load_locale("zh-TW"), } -YT_POOL = HTTPPool.new(YT_URL, capacity: CONFIG.pool_size, timeout: 0.05) +YT_POOL = QUICPool.new(YT_URL, capacity: CONFIG.pool_size, timeout: 0.05) YT_IMG_POOL = HTTPPool.new(YT_IMG_URL, capacity: CONFIG.pool_size, timeout: 0.05) config = CONFIG @@ -1435,6 +1435,7 @@ post "/login" do |env| traceback = IO::Memory.new # See https://github.com/ytdl-org/youtube-dl/blob/2019.04.07/youtube_dl/extractor/youtube.py#L82 + # TODO: Convert to QUIC begin client = make_client(LOGIN_URL) headers = HTTP::Headers.new @@ -1459,7 +1460,7 @@ post "/login" do |env| headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8" headers["Google-Accounts-XSRF"] = "1" - headers["User-Agent"] = random_user_agent + headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" response = client.post("/_/signin/sl/lookup", headers, login_req(lookup_req)) lookup_results = JSON.parse(response.body[5..-1]) @@ -4509,8 +4510,9 @@ get "/api/v1/search/suggestions" do |env| query ||= "" begin - client = make_client(URI.parse("https://suggestqueries.google.com")) - response = client.get("/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback").body + 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 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 0b46cba29..d304a27e2 100644 --- a/src/invidious/helpers/jobs.cr +++ b/src/invidious/helpers/jobs.cr @@ -263,7 +263,7 @@ def bypass_captcha(captcha_key, logger) # "proxyPort" => CONFIG.proxy_port, # "proxyLogin" => CONFIG.proxy_user, # "proxyPassword" => CONFIG.proxy_pass, - # "userAgent" => random_user_agent, + # "userAgent" => "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", }, }.to_json).body) diff --git a/src/invidious/helpers/proxy.cr b/src/invidious/helpers/proxy.cr index 1bd9b3008..4f415ba0b 100644 --- a/src/invidious/helpers/proxy.cr +++ b/src/invidious/helpers/proxy.cr @@ -90,20 +90,6 @@ class HTTPClient < HTTP::Client return opts end - - def exec(request) - if self.host == "www.youtube.com" - request.headers["x-youtube-client-name"] ||= "1" - request.headers["x-youtube-client-version"] ||= "1.20180719" - request.headers["user-agent"] ||= random_user_agent - request.headers["accept-charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7" - request.headers["accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" - request.headers["accept-language"] ||= "en-us,en;q=0.5" - request.headers["cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}" - end - - super - end end def get_proxies(country_code = "US") @@ -115,6 +101,7 @@ def filter_proxies(proxies) proxies.select! do |proxy| begin client = HTTPClient.new(YT_URL) + client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" client.read_timeout = 10.seconds client.connect_timeout = 10.seconds diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index a4b7443eb..8c5ce7a01 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -1,1586 +1,14 @@ +require "lsquic" require "pool/connection" -CHROME_VERSIONS = [ - "68.0.3440.103", - "68.0.3440.104", - "68.0.3440.105", - "68.0.3440.106", - "68.0.3440.107", - "68.0.3440.108", - "68.0.3440.109", - "68.0.3440.110", - "68.0.3440.111", - "68.0.3440.112", - "68.0.3440.113", - "68.0.3440.114", - "68.0.3440.115", - "68.0.3440.116", - "68.0.3440.117", - "68.0.3440.118", - "68.0.3440.119", - "68.0.3440.120", - "68.0.3440.121", - "68.0.3440.122", - "68.0.3440.123", - "68.0.3440.124", - "68.0.3440.125", - "68.0.3440.126", - "68.0.3440.127", - "68.0.3440.128", - "68.0.3440.129", - "68.0.3440.130", - "68.0.3440.131", - "68.0.3440.132", - "68.0.3440.133", - "68.0.3440.134", - "69.0.3497.100", - "69.0.3497.101", - "69.0.3497.102", - "69.0.3497.103", - "69.0.3497.104", - "69.0.3497.105", - "69.0.3497.106", - "69.0.3497.107", - "69.0.3497.108", - "69.0.3497.109", - "69.0.3497.110", - "69.0.3497.111", - "69.0.3497.112", - "69.0.3497.113", - "69.0.3497.114", - "69.0.3497.115", - "69.0.3497.116", - "69.0.3497.117", - "69.0.3497.118", - "69.0.3497.119", - "69.0.3497.120", - "69.0.3497.121", - "69.0.3497.122", - "69.0.3497.123", - "69.0.3497.124", - "69.0.3497.125", - "69.0.3497.126", - "69.0.3497.127", - "69.0.3497.128", - "69.0.3497.28", - "69.0.3497.29", - "69.0.3497.30", - "69.0.3497.31", - "69.0.3497.32", - "69.0.3497.33", - "69.0.3497.34", - "69.0.3497.35", - "69.0.3497.36", - "69.0.3497.37", - "69.0.3497.38", - "69.0.3497.39", - "69.0.3497.40", - "69.0.3497.41", - "69.0.3497.42", - "69.0.3497.43", - "69.0.3497.44", - "69.0.3497.45", - "69.0.3497.46", - "69.0.3497.47", - "69.0.3497.48", - "69.0.3497.49", - "69.0.3497.50", - "69.0.3497.51", - "69.0.3497.52", - "69.0.3497.53", - "69.0.3497.54", - "69.0.3497.55", - "69.0.3497.56", - "69.0.3497.57", - "69.0.3497.58", - "69.0.3497.60", - "69.0.3497.64", - "69.0.3497.65", - "69.0.3497.66", - "69.0.3497.67", - "69.0.3497.68", - "69.0.3497.69", - "69.0.3497.70", - "69.0.3497.71", - "69.0.3497.72", - "69.0.3497.73", - "69.0.3497.74", - "69.0.3497.75", - "69.0.3497.76", - "69.0.3497.77", - "69.0.3497.78", - "69.0.3497.79", - "69.0.3497.80", - "69.0.3497.81", - "69.0.3497.82", - "69.0.3497.83", - "69.0.3497.84", - "69.0.3497.85", - "69.0.3497.86", - "69.0.3497.87", - "69.0.3497.88", - "69.0.3497.89", - "69.0.3497.90", - "69.0.3497.91", - "69.0.3497.92", - "69.0.3497.93", - "69.0.3497.94", - "69.0.3497.95", - "69.0.3497.96", - "69.0.3497.97", - "69.0.3497.98", - "69.0.3497.99", - "70.0.3505.6", - "70.0.3505.7", - "70.0.3505.8", - "70.0.3505.9", - "70.0.3513.0", - "70.0.3513.1", - "70.0.3514.0", - "70.0.3514.1", - "70.0.3514.2", - "70.0.3515.0", - "70.0.3515.1", - "70.0.3515.2", - "70.0.3515.3", - "70.0.3515.4", - "70.0.3516.0", - "70.0.3516.1", - "70.0.3516.2", - "70.0.3516.3", - "70.0.3517.0", - "70.0.3517.1", - "70.0.3518.0", - "70.0.3518.1", - "70.0.3519.0", - "70.0.3519.1", - "70.0.3519.2", - "70.0.3519.3", - "70.0.3520.0", - "70.0.3520.1", - "70.0.3521.0", - "70.0.3521.1", - "70.0.3521.2", - "70.0.3522.0", - "70.0.3522.1", - "70.0.3523.0", - "70.0.3523.1", - "70.0.3523.2", - "70.0.3524.0", - "70.0.3524.1", - "70.0.3524.2", - "70.0.3524.3", - "70.0.3524.4", - "70.0.3525.0", - "70.0.3525.1", - "70.0.3525.2", - "70.0.3525.3", - "70.0.3525.4", - "70.0.3525.5", - "70.0.3526.0", - "70.0.3526.1", - "70.0.3527.0", - "70.0.3527.1", - "70.0.3528.0", - "70.0.3528.1", - "70.0.3528.2", - "70.0.3528.3", - "70.0.3528.4", - "70.0.3529.0", - "70.0.3529.1", - "70.0.3529.2", - "70.0.3529.3", - "70.0.3530.0", - "70.0.3530.1", - "70.0.3530.2", - "70.0.3530.3", - "70.0.3530.4", - "70.0.3531.0", - "70.0.3532.0", - "70.0.3532.1", - "70.0.3532.2", - "70.0.3532.3", - "70.0.3532.4", - "70.0.3532.5", - "70.0.3532.6", - "70.0.3532.7", - "70.0.3532.8", - "70.0.3533.0", - "70.0.3533.1", - "70.0.3533.2", - "70.0.3534.0", - "70.0.3534.1", - "70.0.3534.2", - "70.0.3534.3", - "70.0.3534.4", - "70.0.3535.0", - "70.0.3535.1", - "70.0.3535.2", - "70.0.3535.3", - "70.0.3535.4", - "70.0.3535.5", - "70.0.3536.0", - "70.0.3537.0", - "70.0.3537.1", - "70.0.3537.2", - "70.0.3538.0", - "70.0.3538.1", - "70.0.3538.10", - "70.0.3538.100", - "70.0.3538.101", - "70.0.3538.102", - "70.0.3538.103", - "70.0.3538.104", - "70.0.3538.105", - "70.0.3538.106", - "70.0.3538.107", - "70.0.3538.108", - "70.0.3538.109", - "70.0.3538.11", - "70.0.3538.110", - "70.0.3538.111", - "70.0.3538.112", - "70.0.3538.113", - "70.0.3538.114", - "70.0.3538.115", - "70.0.3538.116", - "70.0.3538.117", - "70.0.3538.118", - "70.0.3538.119", - "70.0.3538.12", - "70.0.3538.120", - "70.0.3538.121", - "70.0.3538.122", - "70.0.3538.123", - "70.0.3538.124", - "70.0.3538.13", - "70.0.3538.14", - "70.0.3538.15", - "70.0.3538.16", - "70.0.3538.17", - "70.0.3538.18", - "70.0.3538.19", - "70.0.3538.2", - "70.0.3538.20", - "70.0.3538.21", - "70.0.3538.22", - "70.0.3538.23", - "70.0.3538.24", - "70.0.3538.25", - "70.0.3538.26", - "70.0.3538.27", - "70.0.3538.28", - "70.0.3538.29", - "70.0.3538.3", - "70.0.3538.30", - "70.0.3538.31", - "70.0.3538.32", - "70.0.3538.33", - "70.0.3538.34", - "70.0.3538.35", - "70.0.3538.36", - "70.0.3538.37", - "70.0.3538.38", - "70.0.3538.39", - "70.0.3538.4", - "70.0.3538.40", - "70.0.3538.41", - "70.0.3538.42", - "70.0.3538.43", - "70.0.3538.44", - "70.0.3538.45", - "70.0.3538.46", - "70.0.3538.47", - "70.0.3538.48", - "70.0.3538.49", - "70.0.3538.5", - "70.0.3538.50", - "70.0.3538.51", - "70.0.3538.52", - "70.0.3538.53", - "70.0.3538.54", - "70.0.3538.55", - "70.0.3538.56", - "70.0.3538.57", - "70.0.3538.58", - "70.0.3538.59", - "70.0.3538.6", - "70.0.3538.60", - "70.0.3538.61", - "70.0.3538.62", - "70.0.3538.63", - "70.0.3538.64", - "70.0.3538.65", - "70.0.3538.66", - "70.0.3538.67", - "70.0.3538.69", - "70.0.3538.7", - "70.0.3538.70", - "70.0.3538.71", - "70.0.3538.72", - "70.0.3538.73", - "70.0.3538.74", - "70.0.3538.75", - "70.0.3538.76", - "70.0.3538.77", - "70.0.3538.78", - "70.0.3538.79", - "70.0.3538.8", - "70.0.3538.80", - "70.0.3538.81", - "70.0.3538.82", - "70.0.3538.83", - "70.0.3538.84", - "70.0.3538.85", - "70.0.3538.86", - "70.0.3538.87", - "70.0.3538.9", - "70.0.3538.93", - "70.0.3538.94", - "70.0.3538.95", - "70.0.3538.96", - "70.0.3538.97", - "70.0.3538.98", - "70.0.3538.99", - "71.0.3539.0", - "71.0.3539.1", - "71.0.3540.0", - "71.0.3540.1", - "71.0.3541.0", - "71.0.3541.1", - "71.0.3542.0", - "71.0.3542.1", - "71.0.3542.2", - "71.0.3543.0", - "71.0.3543.1", - "71.0.3543.2", - "71.0.3543.3", - "71.0.3543.4", - "71.0.3544.0", - "71.0.3544.1", - "71.0.3544.2", - "71.0.3544.3", - "71.0.3544.4", - "71.0.3544.5", - "71.0.3545.0", - "71.0.3545.1", - "71.0.3545.2", - "71.0.3545.3", - "71.0.3545.4", - "71.0.3546.0", - "71.0.3546.1", - "71.0.3546.2", - "71.0.3547.0", - "71.0.3547.1", - "71.0.3548.0", - "71.0.3548.1", - "71.0.3549.0", - "71.0.3549.1", - "71.0.3550.0", - "71.0.3550.1", - "71.0.3550.2", - "71.0.3550.3", - "71.0.3551.0", - "71.0.3551.1", - "71.0.3551.2", - "71.0.3551.3", - "71.0.3552.0", - "71.0.3552.1", - "71.0.3552.2", - "71.0.3552.3", - "71.0.3552.4", - "71.0.3552.5", - "71.0.3552.6", - "71.0.3553.0", - "71.0.3553.1", - "71.0.3553.2", - "71.0.3553.3", - "71.0.3554.0", - "71.0.3554.1", - "71.0.3554.2", - "71.0.3554.3", - "71.0.3554.4", - "71.0.3555.0", - "71.0.3555.1", - "71.0.3555.2", - "71.0.3556.0", - "71.0.3556.1", - "71.0.3557.0", - "71.0.3557.1", - "71.0.3557.2", - "71.0.3558.0", - "71.0.3558.1", - "71.0.3558.2", - "71.0.3559.0", - "71.0.3559.1", - "71.0.3559.2", - "71.0.3559.3", - "71.0.3559.4", - "71.0.3559.5", - "71.0.3559.6", - "71.0.3560.0", - "71.0.3560.1", - "71.0.3561.0", - "71.0.3561.1", - "71.0.3562.0", - "71.0.3562.1", - "71.0.3562.2", - "71.0.3563.0", - "71.0.3564.0", - "71.0.3564.1", - "71.0.3565.0", - "71.0.3565.1", - "71.0.3566.0", - "71.0.3566.1", - "71.0.3567.0", - "71.0.3567.1", - "71.0.3568.0", - "71.0.3568.1", - "71.0.3568.2", - "71.0.3569.0", - "71.0.3569.1", - "71.0.3570.0", - "71.0.3570.1", - "71.0.3571.0", - "71.0.3571.1", - "71.0.3571.2", - "71.0.3572.0", - "71.0.3572.1", - "71.0.3573.0", - "71.0.3573.1", - "71.0.3574.0", - "71.0.3574.1", - "71.0.3575.0", - "71.0.3575.1", - "71.0.3575.2", - "71.0.3576.0", - "71.0.3576.1", - "71.0.3576.2", - "71.0.3577.0", - "71.0.3577.1", - "71.0.3578.0", - "71.0.3578.1", - "71.0.3578.10", - "71.0.3578.100", - "71.0.3578.101", - "71.0.3578.102", - "71.0.3578.103", - "71.0.3578.104", - "71.0.3578.105", - "71.0.3578.106", - "71.0.3578.107", - "71.0.3578.108", - "71.0.3578.109", - "71.0.3578.11", - "71.0.3578.110", - "71.0.3578.111", - "71.0.3578.112", - "71.0.3578.113", - "71.0.3578.114", - "71.0.3578.115", - "71.0.3578.116", - "71.0.3578.117", - "71.0.3578.118", - "71.0.3578.119", - "71.0.3578.12", - "71.0.3578.120", - "71.0.3578.121", - "71.0.3578.122", - "71.0.3578.123", - "71.0.3578.124", - "71.0.3578.125", - "71.0.3578.126", - "71.0.3578.127", - "71.0.3578.128", - "71.0.3578.129", - "71.0.3578.13", - "71.0.3578.130", - "71.0.3578.131", - "71.0.3578.132", - "71.0.3578.133", - "71.0.3578.134", - "71.0.3578.135", - "71.0.3578.136", - "71.0.3578.137", - "71.0.3578.138", - "71.0.3578.139", - "71.0.3578.14", - "71.0.3578.140", - "71.0.3578.141", - "71.0.3578.15", - "71.0.3578.16", - "71.0.3578.17", - "71.0.3578.18", - "71.0.3578.19", - "71.0.3578.2", - "71.0.3578.20", - "71.0.3578.21", - "71.0.3578.22", - "71.0.3578.23", - "71.0.3578.24", - "71.0.3578.25", - "71.0.3578.26", - "71.0.3578.27", - "71.0.3578.28", - "71.0.3578.29", - "71.0.3578.3", - "71.0.3578.30", - "71.0.3578.31", - "71.0.3578.32", - "71.0.3578.33", - "71.0.3578.34", - "71.0.3578.35", - "71.0.3578.36", - "71.0.3578.37", - "71.0.3578.38", - "71.0.3578.39", - "71.0.3578.4", - "71.0.3578.40", - "71.0.3578.41", - "71.0.3578.42", - "71.0.3578.43", - "71.0.3578.44", - "71.0.3578.45", - "71.0.3578.46", - "71.0.3578.47", - "71.0.3578.48", - "71.0.3578.49", - "71.0.3578.5", - "71.0.3578.50", - "71.0.3578.51", - "71.0.3578.52", - "71.0.3578.53", - "71.0.3578.54", - "71.0.3578.55", - "71.0.3578.56", - "71.0.3578.57", - "71.0.3578.58", - "71.0.3578.59", - "71.0.3578.6", - "71.0.3578.60", - "71.0.3578.61", - "71.0.3578.62", - "71.0.3578.63", - "71.0.3578.64", - "71.0.3578.65", - "71.0.3578.66", - "71.0.3578.67", - "71.0.3578.68", - "71.0.3578.69", - "71.0.3578.7", - "71.0.3578.70", - "71.0.3578.71", - "71.0.3578.72", - "71.0.3578.73", - "71.0.3578.74", - "71.0.3578.75", - "71.0.3578.76", - "71.0.3578.77", - "71.0.3578.78", - "71.0.3578.79", - "71.0.3578.8", - "71.0.3578.80", - "71.0.3578.81", - "71.0.3578.82", - "71.0.3578.83", - "71.0.3578.84", - "71.0.3578.85", - "71.0.3578.86", - "71.0.3578.87", - "71.0.3578.88", - "71.0.3578.89", - "71.0.3578.9", - "71.0.3578.90", - "71.0.3578.91", - "71.0.3578.92", - "71.0.3578.93", - "71.0.3578.94", - "71.0.3578.95", - "71.0.3578.96", - "71.0.3578.97", - "71.0.3578.98", - "71.0.3578.99", - "72.0.3579.0", - "72.0.3579.1", - "72.0.3580.0", - "72.0.3580.1", - "72.0.3581.0", - "72.0.3581.1", - "72.0.3581.2", - "72.0.3581.3", - "72.0.3581.4", - "72.0.3582.0", - "72.0.3583.0", - "72.0.3583.1", - "72.0.3583.2", - "72.0.3584.0", - "72.0.3584.1", - "72.0.3585.0", - "72.0.3585.1", - "72.0.3586.0", - "72.0.3586.1", - "72.0.3586.2", - "72.0.3587.0", - "72.0.3588.0", - "72.0.3588.1", - "72.0.3589.0", - "72.0.3589.1", - "72.0.3589.2", - "72.0.3589.3", - "72.0.3590.0", - "72.0.3590.1", - "72.0.3591.0", - "72.0.3591.1", - "72.0.3591.2", - "72.0.3591.3", - "72.0.3592.0", - "72.0.3592.1", - "72.0.3592.2", - "72.0.3593.0", - "72.0.3593.1", - "72.0.3593.2", - "72.0.3594.0", - "72.0.3594.1", - "72.0.3595.0", - "72.0.3595.1", - "72.0.3595.2", - "72.0.3596.0", - "72.0.3596.1", - "72.0.3596.2", - "72.0.3597.0", - "72.0.3597.1", - "72.0.3598.0", - "72.0.3598.1", - "72.0.3599.0", - "72.0.3599.1", - "72.0.3599.2", - "72.0.3599.3", - "72.0.3600.0", - "72.0.3600.1", - "72.0.3601.0", - "72.0.3601.1", - "72.0.3602.0", - "72.0.3602.1", - "72.0.3602.2", - "72.0.3602.3", - "72.0.3603.0", - "72.0.3603.1", - "72.0.3603.2", - "72.0.3604.0", - "72.0.3604.1", - "72.0.3605.0", - "72.0.3605.1", - "72.0.3605.2", - "72.0.3605.3", - "72.0.3606.0", - "72.0.3606.1", - "72.0.3606.2", - "72.0.3607.0", - "72.0.3607.1", - "72.0.3608.0", - "72.0.3608.1", - "72.0.3608.2", - "72.0.3608.3", - "72.0.3608.4", - "72.0.3608.5", - "72.0.3609.0", - "72.0.3609.1", - "72.0.3609.2", - "72.0.3609.3", - "72.0.3610.0", - "72.0.3610.1", - "72.0.3610.2", - "72.0.3610.3", - "72.0.3610.4", - "72.0.3611.0", - "72.0.3611.1", - "72.0.3611.2", - "72.0.3612.0", - "72.0.3612.1", - "72.0.3612.2", - "72.0.3613.0", - "72.0.3613.1", - "72.0.3614.0", - "72.0.3614.1", - "72.0.3615.0", - "72.0.3615.1", - "72.0.3616.0", - "72.0.3616.1", - "72.0.3617.0", - "72.0.3617.1", - "72.0.3618.0", - "72.0.3618.1", - "72.0.3619.0", - "72.0.3619.1", - "72.0.3620.0", - "72.0.3620.1", - "72.0.3621.0", - "72.0.3621.1", - "72.0.3622.0", - "72.0.3622.1", - "72.0.3622.2", - "72.0.3622.3", - "72.0.3623.0", - "72.0.3623.1", - "72.0.3623.2", - "72.0.3623.3", - "72.0.3623.4", - "72.0.3624.0", - "72.0.3624.1", - "72.0.3624.2", - "72.0.3624.3", - "72.0.3624.4", - "72.0.3625.0", - "72.0.3625.1", - "72.0.3625.2", - "72.0.3626.0", - "72.0.3626.1", - "72.0.3626.10", - "72.0.3626.100", - "72.0.3626.101", - "72.0.3626.102", - "72.0.3626.103", - "72.0.3626.105", - "72.0.3626.107", - "72.0.3626.108", - "72.0.3626.109", - "72.0.3626.11", - "72.0.3626.110", - "72.0.3626.111", - "72.0.3626.112", - "72.0.3626.113", - "72.0.3626.114", - "72.0.3626.115", - "72.0.3626.116", - "72.0.3626.117", - "72.0.3626.118", - "72.0.3626.119", - "72.0.3626.12", - "72.0.3626.120", - "72.0.3626.121", - "72.0.3626.122", - "72.0.3626.13", - "72.0.3626.14", - "72.0.3626.15", - "72.0.3626.16", - "72.0.3626.17", - "72.0.3626.18", - "72.0.3626.19", - "72.0.3626.2", - "72.0.3626.20", - "72.0.3626.21", - "72.0.3626.22", - "72.0.3626.23", - "72.0.3626.24", - "72.0.3626.25", - "72.0.3626.26", - "72.0.3626.27", - "72.0.3626.28", - "72.0.3626.29", - "72.0.3626.3", - "72.0.3626.30", - "72.0.3626.31", - "72.0.3626.32", - "72.0.3626.33", - "72.0.3626.34", - "72.0.3626.35", - "72.0.3626.36", - "72.0.3626.37", - "72.0.3626.38", - "72.0.3626.39", - "72.0.3626.4", - "72.0.3626.40", - "72.0.3626.41", - "72.0.3626.42", - "72.0.3626.43", - "72.0.3626.44", - "72.0.3626.45", - "72.0.3626.46", - "72.0.3626.47", - "72.0.3626.48", - "72.0.3626.49", - "72.0.3626.5", - "72.0.3626.50", - "72.0.3626.51", - "72.0.3626.52", - "72.0.3626.53", - "72.0.3626.54", - "72.0.3626.55", - "72.0.3626.56", - "72.0.3626.57", - "72.0.3626.58", - "72.0.3626.59", - "72.0.3626.6", - "72.0.3626.60", - "72.0.3626.61", - "72.0.3626.62", - "72.0.3626.63", - "72.0.3626.64", - "72.0.3626.65", - "72.0.3626.66", - "72.0.3626.67", - "72.0.3626.68", - "72.0.3626.69", - "72.0.3626.7", - "72.0.3626.70", - "72.0.3626.71", - "72.0.3626.72", - "72.0.3626.73", - "72.0.3626.74", - "72.0.3626.75", - "72.0.3626.76", - "72.0.3626.77", - "72.0.3626.78", - "72.0.3626.79", - "72.0.3626.8", - "72.0.3626.80", - "72.0.3626.81", - "72.0.3626.82", - "72.0.3626.83", - "72.0.3626.84", - "72.0.3626.85", - "72.0.3626.86", - "72.0.3626.87", - "72.0.3626.88", - "72.0.3626.89", - "72.0.3626.9", - "72.0.3626.90", - "72.0.3626.91", - "72.0.3626.92", - "72.0.3626.93", - "72.0.3626.94", - "72.0.3626.95", - "72.0.3626.96", - "72.0.3626.97", - "72.0.3626.98", - "72.0.3626.99", - "73.0.3627.0", - "73.0.3627.1", - "73.0.3628.0", - "73.0.3628.1", - "73.0.3628.2", - "73.0.3628.3", - "73.0.3629.0", - "73.0.3629.1", - "73.0.3630.0", - "73.0.3630.1", - "73.0.3631.0", - "73.0.3631.1", - "73.0.3631.2", - "73.0.3632.0", - "73.0.3632.1", - "73.0.3632.2", - "73.0.3632.3", - "73.0.3632.4", - "73.0.3632.5", - "73.0.3633.0", - "73.0.3633.1", - "73.0.3633.2", - "73.0.3634.0", - "73.0.3634.1", - "73.0.3634.2", - "73.0.3635.0", - "73.0.3635.1", - "73.0.3635.2", - "73.0.3635.3", - "73.0.3636.0", - "73.0.3636.1", - "73.0.3636.2", - "73.0.3637.0", - "73.0.3637.1", - "73.0.3638.0", - "73.0.3638.1", - "73.0.3638.2", - "73.0.3639.0", - "73.0.3639.1", - "73.0.3640.0", - "73.0.3640.1", - "73.0.3641.0", - "73.0.3641.1", - "73.0.3642.0", - "73.0.3642.1", - "73.0.3643.0", - "73.0.3643.1", - "73.0.3643.2", - "73.0.3644.0", - "73.0.3645.0", - "73.0.3645.1", - "73.0.3645.2", - "73.0.3646.0", - "73.0.3646.1", - "73.0.3646.2", - "73.0.3647.0", - "73.0.3647.1", - "73.0.3647.2", - "73.0.3648.0", - "73.0.3648.1", - "73.0.3648.2", - "73.0.3649.0", - "73.0.3649.1", - "73.0.3650.0", - "73.0.3650.1", - "73.0.3651.0", - "73.0.3651.1", - "73.0.3652.0", - "73.0.3652.1", - "73.0.3653.0", - "73.0.3653.1", - "73.0.3654.0", - "73.0.3654.1", - "73.0.3655.0", - "73.0.3655.1", - "73.0.3656.0", - "73.0.3656.1", - "73.0.3657.0", - "73.0.3657.1", - "73.0.3658.0", - "73.0.3658.1", - "73.0.3659.0", - "73.0.3659.1", - "73.0.3660.0", - "73.0.3660.1", - "73.0.3660.2", - "73.0.3661.0", - "73.0.3661.1", - "73.0.3662.0", - "73.0.3662.1", - "73.0.3663.0", - "73.0.3663.1", - "73.0.3663.2", - "73.0.3664.0", - "73.0.3664.1", - "73.0.3664.2", - "73.0.3664.3", - "73.0.3664.4", - "73.0.3665.0", - "73.0.3665.1", - "73.0.3665.2", - "73.0.3665.3", - "73.0.3665.4", - "73.0.3666.0", - "73.0.3666.1", - "73.0.3667.0", - "73.0.3667.1", - "73.0.3667.2", - "73.0.3668.0", - "73.0.3668.1", - "73.0.3668.2", - "73.0.3669.0", - "73.0.3669.1", - "73.0.3670.0", - "73.0.3670.1", - "73.0.3671.0", - "73.0.3671.1", - "73.0.3671.2", - "73.0.3671.3", - "73.0.3672.0", - "73.0.3672.1", - "73.0.3673.0", - "73.0.3673.1", - "73.0.3673.2", - "73.0.3674.0", - "73.0.3674.1", - "73.0.3674.2", - "73.0.3676.0", - "73.0.3676.1", - "73.0.3677.0", - "73.0.3677.1", - "73.0.3678.0", - "73.0.3678.1", - "73.0.3678.2", - "73.0.3679.0", - "73.0.3679.1", - "73.0.3680.0", - "73.0.3680.1", - "73.0.3681.0", - "73.0.3681.1", - "73.0.3681.2", - "73.0.3681.3", - "73.0.3681.4", - "73.0.3682.0", - "73.0.3682.1", - "73.0.3683.0", - "73.0.3683.1", - "73.0.3683.10", - "73.0.3683.100", - "73.0.3683.101", - "73.0.3683.102", - "73.0.3683.103", - "73.0.3683.104", - "73.0.3683.105", - "73.0.3683.106", - "73.0.3683.107", - "73.0.3683.108", - "73.0.3683.109", - "73.0.3683.11", - "73.0.3683.110", - "73.0.3683.111", - "73.0.3683.112", - "73.0.3683.113", - "73.0.3683.114", - "73.0.3683.115", - "73.0.3683.116", - "73.0.3683.117", - "73.0.3683.118", - "73.0.3683.119", - "73.0.3683.12", - "73.0.3683.120", - "73.0.3683.121", - "73.0.3683.13", - "73.0.3683.14", - "73.0.3683.15", - "73.0.3683.16", - "73.0.3683.17", - "73.0.3683.18", - "73.0.3683.19", - "73.0.3683.2", - "73.0.3683.20", - "73.0.3683.21", - "73.0.3683.22", - "73.0.3683.23", - "73.0.3683.24", - "73.0.3683.25", - "73.0.3683.26", - "73.0.3683.27", - "73.0.3683.28", - "73.0.3683.29", - "73.0.3683.3", - "73.0.3683.31", - "73.0.3683.32", - "73.0.3683.33", - "73.0.3683.34", - "73.0.3683.35", - "73.0.3683.36", - "73.0.3683.37", - "73.0.3683.38", - "73.0.3683.39", - "73.0.3683.4", - "73.0.3683.40", - "73.0.3683.41", - "73.0.3683.42", - "73.0.3683.43", - "73.0.3683.44", - "73.0.3683.45", - "73.0.3683.46", - "73.0.3683.47", - "73.0.3683.48", - "73.0.3683.49", - "73.0.3683.5", - "73.0.3683.50", - "73.0.3683.51", - "73.0.3683.52", - "73.0.3683.53", - "73.0.3683.54", - "73.0.3683.55", - "73.0.3683.56", - "73.0.3683.57", - "73.0.3683.58", - "73.0.3683.59", - "73.0.3683.6", - "73.0.3683.60", - "73.0.3683.61", - "73.0.3683.62", - "73.0.3683.63", - "73.0.3683.64", - "73.0.3683.65", - "73.0.3683.66", - "73.0.3683.67", - "73.0.3683.68", - "73.0.3683.69", - "73.0.3683.7", - "73.0.3683.70", - "73.0.3683.71", - "73.0.3683.72", - "73.0.3683.73", - "73.0.3683.74", - "73.0.3683.75", - "73.0.3683.76", - "73.0.3683.77", - "73.0.3683.78", - "73.0.3683.79", - "73.0.3683.8", - "73.0.3683.80", - "73.0.3683.81", - "73.0.3683.82", - "73.0.3683.83", - "73.0.3683.84", - "73.0.3683.85", - "73.0.3683.86", - "73.0.3683.87", - "73.0.3683.88", - "73.0.3683.89", - "73.0.3683.9", - "73.0.3683.90", - "73.0.3683.91", - "73.0.3683.92", - "73.0.3683.93", - "73.0.3683.94", - "73.0.3683.95", - "73.0.3683.96", - "73.0.3683.97", - "73.0.3683.98", - "73.0.3683.99", - "74.0.3684.0", - "74.0.3684.1", - "74.0.3685.0", - "74.0.3685.1", - "74.0.3686.0", - "74.0.3686.1", - "74.0.3686.2", - "74.0.3686.3", - "74.0.3686.4", - "74.0.3687.0", - "74.0.3687.1", - "74.0.3687.2", - "74.0.3687.3", - "74.0.3688.0", - "74.0.3688.1", - "74.0.3689.0", - "74.0.3689.1", - "74.0.3690.0", - "74.0.3690.1", - "74.0.3691.0", - "74.0.3691.1", - "74.0.3692.0", - "74.0.3692.1", - "74.0.3693.0", - "74.0.3693.1", - "74.0.3693.2", - "74.0.3693.3", - "74.0.3693.4", - "74.0.3693.5", - "74.0.3693.6", - "74.0.3694.0", - "74.0.3694.1", - "74.0.3694.2", - "74.0.3694.3", - "74.0.3694.4", - "74.0.3694.5", - "74.0.3694.6", - "74.0.3694.7", - "74.0.3694.8", - "74.0.3696.0", - "74.0.3696.1", - "74.0.3696.2", - "74.0.3698.0", - "74.0.3699.0", - "74.0.3699.1", - "74.0.3699.2", - "74.0.3699.3", - "74.0.3700.0", - "74.0.3700.1", - "74.0.3701.0", - "74.0.3701.1", - "74.0.3702.0", - "74.0.3702.1", - "74.0.3702.2", - "74.0.3702.3", - "74.0.3703.0", - "74.0.3703.1", - "74.0.3703.2", - "74.0.3703.3", - "74.0.3704.0", - "74.0.3704.1", - "74.0.3704.2", - "74.0.3704.3", - "74.0.3704.4", - "74.0.3704.5", - "74.0.3704.6", - "74.0.3704.7", - "74.0.3704.8", - "74.0.3704.9", - "74.0.3705.0", - "74.0.3705.1", - "74.0.3706.0", - "74.0.3706.1", - "74.0.3706.2", - "74.0.3706.3", - "74.0.3706.4", - "74.0.3706.5", - "74.0.3706.6", - "74.0.3706.7", - "74.0.3708.0", - "74.0.3709.0", - "74.0.3709.1", - "74.0.3710.0", - "74.0.3710.1", - "74.0.3710.2", - "74.0.3711.0", - "74.0.3711.1", - "74.0.3711.2", - "74.0.3712.0", - "74.0.3712.1", - "74.0.3712.2", - "74.0.3713.0", - "74.0.3713.1", - "74.0.3713.3", - "74.0.3714.0", - "74.0.3714.1", - "74.0.3714.2", - "74.0.3715.0", - "74.0.3715.1", - "74.0.3716.0", - "74.0.3716.1", - "74.0.3717.0", - "74.0.3717.1", - "74.0.3717.2", - "74.0.3718.0", - "74.0.3718.1", - "74.0.3718.2", - "74.0.3718.3", - "74.0.3718.4", - "74.0.3718.5", - "74.0.3718.6", - "74.0.3718.7", - "74.0.3718.8", - "74.0.3718.9", - "74.0.3719.0", - "74.0.3719.1", - "74.0.3719.2", - "74.0.3719.3", - "74.0.3719.4", - "74.0.3719.5", - "74.0.3720.0", - "74.0.3720.1", - "74.0.3720.2", - "74.0.3720.3", - "74.0.3720.4", - "74.0.3720.5", - "74.0.3720.6", - "74.0.3721.0", - "74.0.3721.1", - "74.0.3721.2", - "74.0.3721.3", - "74.0.3722.0", - "74.0.3722.1", - "74.0.3723.0", - "74.0.3723.1", - "74.0.3724.0", - "74.0.3724.1", - "74.0.3724.2", - "74.0.3724.3", - "74.0.3724.4", - "74.0.3724.5", - "74.0.3724.6", - "74.0.3724.7", - "74.0.3724.8", - "74.0.3725.0", - "74.0.3725.1", - "74.0.3725.2", - "74.0.3725.3", - "74.0.3725.4", - "74.0.3726.0", - "74.0.3726.1", - "74.0.3726.2", - "74.0.3726.3", - "74.0.3726.4", - "74.0.3728.0", - "74.0.3729.0", - "74.0.3729.1", - "74.0.3729.10", - "74.0.3729.100", - "74.0.3729.101", - "74.0.3729.102", - "74.0.3729.103", - "74.0.3729.104", - "74.0.3729.105", - "74.0.3729.106", - "74.0.3729.107", - "74.0.3729.108", - "74.0.3729.109", - "74.0.3729.11", - "74.0.3729.110", - "74.0.3729.111", - "74.0.3729.112", - "74.0.3729.113", - "74.0.3729.114", - "74.0.3729.115", - "74.0.3729.116", - "74.0.3729.117", - "74.0.3729.118", - "74.0.3729.119", - "74.0.3729.12", - "74.0.3729.120", - "74.0.3729.121", - "74.0.3729.122", - "74.0.3729.123", - "74.0.3729.124", - "74.0.3729.125", - "74.0.3729.126", - "74.0.3729.127", - "74.0.3729.128", - "74.0.3729.129", - "74.0.3729.13", - "74.0.3729.14", - "74.0.3729.15", - "74.0.3729.16", - "74.0.3729.17", - "74.0.3729.18", - "74.0.3729.19", - "74.0.3729.2", - "74.0.3729.20", - "74.0.3729.21", - "74.0.3729.22", - "74.0.3729.23", - "74.0.3729.24", - "74.0.3729.25", - "74.0.3729.26", - "74.0.3729.27", - "74.0.3729.28", - "74.0.3729.29", - "74.0.3729.3", - "74.0.3729.30", - "74.0.3729.31", - "74.0.3729.32", - "74.0.3729.33", - "74.0.3729.34", - "74.0.3729.35", - "74.0.3729.36", - "74.0.3729.37", - "74.0.3729.38", - "74.0.3729.39", - "74.0.3729.4", - "74.0.3729.40", - "74.0.3729.41", - "74.0.3729.42", - "74.0.3729.43", - "74.0.3729.44", - "74.0.3729.45", - "74.0.3729.46", - "74.0.3729.47", - "74.0.3729.48", - "74.0.3729.49", - "74.0.3729.5", - "74.0.3729.50", - "74.0.3729.51", - "74.0.3729.52", - "74.0.3729.53", - "74.0.3729.54", - "74.0.3729.55", - "74.0.3729.56", - "74.0.3729.57", - "74.0.3729.58", - "74.0.3729.59", - "74.0.3729.6", - "74.0.3729.60", - "74.0.3729.61", - "74.0.3729.62", - "74.0.3729.63", - "74.0.3729.64", - "74.0.3729.65", - "74.0.3729.66", - "74.0.3729.67", - "74.0.3729.68", - "74.0.3729.69", - "74.0.3729.7", - "74.0.3729.70", - "74.0.3729.71", - "74.0.3729.72", - "74.0.3729.73", - "74.0.3729.74", - "74.0.3729.75", - "74.0.3729.76", - "74.0.3729.77", - "74.0.3729.78", - "74.0.3729.79", - "74.0.3729.8", - "74.0.3729.80", - "74.0.3729.81", - "74.0.3729.82", - "74.0.3729.83", - "74.0.3729.84", - "74.0.3729.85", - "74.0.3729.86", - "74.0.3729.87", - "74.0.3729.88", - "74.0.3729.89", - "74.0.3729.9", - "74.0.3729.90", - "74.0.3729.91", - "74.0.3729.92", - "74.0.3729.93", - "74.0.3729.94", - "74.0.3729.95", - "74.0.3729.96", - "74.0.3729.97", - "74.0.3729.98", - "74.0.3729.99", - "75.0.3730.0", - "75.0.3730.1", - "75.0.3730.2", - "75.0.3730.3", - "75.0.3730.4", - "75.0.3730.5", - "75.0.3731.0", - "75.0.3731.2", - "75.0.3731.3", - "75.0.3732.0", - "75.0.3732.1", - "75.0.3733.0", - "75.0.3733.1", - "75.0.3734.0", - "75.0.3734.1", - "75.0.3735.0", - "75.0.3735.1", - "75.0.3736.0", - "75.0.3736.1", - "75.0.3737.0", - "75.0.3737.1", - "75.0.3738.0", - "75.0.3738.1", - "75.0.3738.2", - "75.0.3738.3", - "75.0.3738.4", - "75.0.3739.0", - "75.0.3739.1", - "75.0.3740.0", - "75.0.3740.1", - "75.0.3740.2", - "75.0.3740.3", - "75.0.3740.4", - "75.0.3740.5", - "75.0.3741.0", - "75.0.3741.1", - "75.0.3741.2", - "75.0.3744.0", - "75.0.3744.1", - "75.0.3744.2", - "75.0.3745.0", - "75.0.3745.1", - "75.0.3745.2", - "75.0.3745.3", - "75.0.3745.4", - "75.0.3745.5", - "75.0.3746.0", - "75.0.3746.1", - "75.0.3746.2", - "75.0.3746.3", - "75.0.3746.4", - "75.0.3747.0", - "75.0.3747.1", - "75.0.3748.0", - "75.0.3748.1", - "75.0.3749.0", - "75.0.3749.1", - "75.0.3749.2", - "75.0.3749.3", - "75.0.3750.0", - "75.0.3751.0", - "75.0.3751.1", - "75.0.3752.0", - "75.0.3752.1", - "75.0.3752.2", - "75.0.3753.0", - "75.0.3753.1", - "75.0.3753.2", - "75.0.3753.3", - "75.0.3753.4", - "75.0.3754.0", - "75.0.3754.1", - "75.0.3754.2", - "75.0.3755.0", - "75.0.3755.1", - "75.0.3755.2", - "75.0.3755.3", - "75.0.3756.0", - "75.0.3756.1", - "75.0.3757.0", - "75.0.3757.1", - "75.0.3758.0", - "75.0.3758.1", - "75.0.3759.0", - "75.0.3759.1", - "75.0.3759.2", - "75.0.3759.3", - "75.0.3759.4", - "75.0.3759.5", - "75.0.3759.6", - "75.0.3759.7", - "75.0.3759.8", - "75.0.3760.0", - "75.0.3761.0", - "75.0.3761.1", - "75.0.3761.2", - "75.0.3761.3", - "75.0.3761.4", - "75.0.3762.0", - "75.0.3762.1", - "75.0.3763.0", - "75.0.3763.1", - "75.0.3763.2", - "75.0.3764.0", - "75.0.3764.1", - "75.0.3765.0", - "75.0.3765.1", - "75.0.3766.0", - "75.0.3766.1", - "75.0.3766.2", - "75.0.3766.3", - "75.0.3767.0", - "75.0.3767.1", - "75.0.3767.2", - "75.0.3768.0", - "75.0.3768.1", - "75.0.3768.2", - "75.0.3768.3", - "75.0.3768.4", - "75.0.3768.5", - "75.0.3768.6", - "75.0.3769.0", - "75.0.3769.1", - "75.0.3769.2", - "75.0.3769.3", - "75.0.3769.4", - "75.0.3769.5", - "75.0.3770.0", - "75.0.3770.1", - "75.0.3770.10", - "75.0.3770.11", - "75.0.3770.12", - "75.0.3770.13", - "75.0.3770.14", - "75.0.3770.15", - "75.0.3770.2", - "75.0.3770.3", - "75.0.3770.4", - "75.0.3770.5", - "75.0.3770.6", - "75.0.3770.7", - "75.0.3770.8", - "75.0.3770.9", - "76.0.3771.0", - "76.0.3771.1", - "76.0.3772.0", - "76.0.3772.1", - "76.0.3773.0", - "76.0.3773.1", - "76.0.3774.0", - "76.0.3774.1", - "76.0.3775.0", - "76.0.3775.1", - "76.0.3775.2", - "76.0.3775.3", - "76.0.3775.4", - "76.0.3775.5", - "76.0.3776.0", - "76.0.3776.1", - "76.0.3776.2", - "76.0.3776.3", - "76.0.3776.4", - "76.0.3777.0", - "76.0.3777.1", - "76.0.3778.0", - "76.0.3778.1", - "76.0.3779.0", - "76.0.3779.1", - "76.0.3780.0", - "76.0.3780.1", - "76.0.3780.2", - "76.0.3780.3", -] - -def random_user_agent - return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{CHROME_VERSIONS[rand(CHROME_VERSIONS.size)]} Safari/537.36" +def add_yt_headers(request) + request.headers["x-youtube-client-name"] ||= "1" + request.headers["x-youtube-client-version"] ||= "1.20180719" + request.headers["user-agent"] ||= "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36" + request.headers["accept-charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7" + request.headers["accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + request.headers["accept-language"] ||= "en-us,en;q=0.5" + request.headers["cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}" end struct HTTPPool @@ -1618,6 +46,7 @@ struct HTTPPool response rescue ex conn = HTTPClient.new(url) + conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" conn.family = (url.host == "www.youtube.com" || url.host == "suggestqueries.google.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC conn.read_timeout = 10.seconds conn.connect_timeout = 10.seconds @@ -1630,6 +59,7 @@ struct HTTPPool private def build_pool ConnectionPool(HTTPClient).new(capacity: capacity, timeout: timeout) do client = HTTPClient.new(url) + client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" client.family = (url.host == "www.youtube.com" || url.host == "suggestqueries.google.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC client.read_timeout = 10.seconds client.connect_timeout = 10.seconds @@ -1638,6 +68,46 @@ struct HTTPPool end end +struct QUICPool + property! url : URI + property! capacity : Int32 + property! timeout : Float64 + + def initialize(url : URI, @capacity = 5, @timeout = 5.0) + @url = url + end + + def client(region = nil, &block) + begin + if region + client = HTTPClient.new(url) + client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" + client.read_timeout = 10.seconds + client.connect_timeout = 10.seconds + + PROXY_LIST[region]?.try &.sample(40).each do |proxy| + begin + proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port]) + client.set_proxy(proxy) + break + rescue ex + end + end + + yield client + else + conn = QUIC::Client.new(url) + conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" + yield conn + end + rescue ex + conn = QUIC::Client.new(url) + conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com" + yield conn + end + end +end + # See http://www.evanmiller.org/how-not-to-sort-by-average-rating.html def ci_lower_bound(pos, n) if n == 0