mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-10-31 04:32:02 +00:00 
			
		
		
		
	
							
								
								
									
										2
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -19,7 +19,7 @@ jobs: | ||||
|       - name: Install Crystal | ||||
|         uses: oprypin/install-crystal@v1.2.4 | ||||
|         with: | ||||
|           crystal: 0.35.1 | ||||
|           crystal: 0.36.0 | ||||
|        | ||||
|       - name: Cache Shards | ||||
|         uses: actions/cache@v2 | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| FROM crystallang/crystal:0.35.1-alpine AS builder | ||||
| FROM crystallang/crystal:0.36.0-alpine AS builder | ||||
| RUN apk add --no-cache curl sqlite-static | ||||
| WORKDIR /invidious | ||||
| COPY ./shard.yml ./shard.yml | ||||
|   | ||||
| @@ -29,6 +29,6 @@ dependencies: | ||||
|     github: iv-org/lsquic.cr | ||||
|     version: ~> 2.18.1-1 | ||||
|  | ||||
| crystal: 0.35.1 | ||||
| crystal: 0.36.0 | ||||
|  | ||||
| license: AGPLv3 | ||||
|   | ||||
| @@ -1428,9 +1428,9 @@ get "/feed/playlist/:plid" do |env| | ||||
|     node.attributes.each do |attribute| | ||||
|       case attribute.name | ||||
|       when "url", "href" | ||||
|         full_path = URI.parse(node[attribute.name]).full_path | ||||
|         query_string_opt = full_path.starts_with?("/watch?v=") ? "&#{params}" : "" | ||||
|         node[attribute.name] = "#{HOST_URL}#{full_path}#{query_string_opt}" | ||||
|         request_target = URI.parse(node[attribute.name]).request_target | ||||
|         query_string_opt = request_target.starts_with?("/watch?v=") ? "&#{params}" : "" | ||||
|         node[attribute.name] = "#{HOST_URL}#{request_target}#{query_string_opt}" | ||||
|       else nil # Skip | ||||
|       end | ||||
|     end | ||||
| @@ -1439,7 +1439,7 @@ get "/feed/playlist/:plid" do |env| | ||||
|   document = document.to_xml(options: XML::SaveOptions::NO_DECL) | ||||
|  | ||||
|   document.scan(/<uri>(?<url>[^<]+)<\/uri>/).each do |match| | ||||
|     content = "#{HOST_URL}#{URI.parse(match["url"]).full_path}" | ||||
|     content = "#{HOST_URL}#{URI.parse(match["url"]).request_target}" | ||||
|     document = document.gsub(match[0], "<uri>#{content}</uri>") | ||||
|   end | ||||
|  | ||||
| @@ -1634,7 +1634,7 @@ end | ||||
|  | ||||
| get "/attribution_link" do |env| | ||||
|   if query = env.params.query["u"]? | ||||
|     url = URI.parse(query).full_path | ||||
|     url = URI.parse(query).request_target | ||||
|   else | ||||
|     url = "/" | ||||
|   end | ||||
| @@ -1978,7 +1978,7 @@ get "/api/v1/captions/:id" do |env| | ||||
|     caption = caption[0] | ||||
|   end | ||||
|  | ||||
|   url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path | ||||
|   url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").request_target | ||||
|  | ||||
|   # 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 | ||||
| @@ -3184,7 +3184,7 @@ get "/api/manifest/dash/id/:id" do |env| | ||||
|   end | ||||
|  | ||||
|   if dashmpd = video.dash_manifest_url | ||||
|     manifest = YT_POOL.client &.get(URI.parse(dashmpd).full_path).body | ||||
|     manifest = YT_POOL.client &.get(URI.parse(dashmpd).request_target).body | ||||
|  | ||||
|     manifest = manifest.gsub(/<BaseURL>[^<]+<\/BaseURL>/) do |baseurl| | ||||
|       url = baseurl.lchop("<BaseURL>") | ||||
| @@ -3192,7 +3192,7 @@ get "/api/manifest/dash/id/:id" do |env| | ||||
|  | ||||
|       if local | ||||
|         uri = URI.parse(url) | ||||
|         url = "#{uri.full_path}host/#{uri.host}/" | ||||
|         url = "#{uri.request_target}host/#{uri.host}/" | ||||
|       end | ||||
|  | ||||
|       "<BaseURL>#{url}</BaseURL>" | ||||
| @@ -3205,7 +3205,7 @@ get "/api/manifest/dash/id/:id" do |env| | ||||
|  | ||||
|   if local | ||||
|     adaptive_fmts.each do |fmt| | ||||
|       fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) | ||||
|       fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @@ -3403,7 +3403,7 @@ get "/latest_version" do |env| | ||||
|     next | ||||
|   end | ||||
|  | ||||
|   url = URI.parse(url).full_path.not_nil! if local | ||||
|   url = URI.parse(url).request_target.not_nil! if local | ||||
|   url = "#{url}&title=#{title}" if title | ||||
|  | ||||
|   env.redirect url | ||||
| @@ -3515,7 +3515,7 @@ get "/videoplayback" do |env| | ||||
|           client = make_client(URI.parse(new_host), region) | ||||
|         end | ||||
|  | ||||
|         url = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" | ||||
|         url = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" | ||||
|       else | ||||
|         break | ||||
|       end | ||||
| @@ -3555,7 +3555,7 @@ get "/videoplayback" do |env| | ||||
|  | ||||
|         if location = response.headers["Location"]? | ||||
|           location = URI.parse(location) | ||||
|           location = "#{location.full_path}&host=#{location.host}" | ||||
|           location = "#{location.request_target}&host=#{location.host}" | ||||
|  | ||||
|           if region | ||||
|             location += "®ion=#{region}" | ||||
| @@ -3619,7 +3619,7 @@ get "/videoplayback" do |env| | ||||
|  | ||||
|             if location = response.headers["Location"]? | ||||
|               location = URI.parse(location) | ||||
|               location = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" | ||||
|               location = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" | ||||
|  | ||||
|               env.redirect location | ||||
|               break | ||||
| @@ -3859,7 +3859,7 @@ end | ||||
| get "/watch_videos" do |env| | ||||
|   response = YT_POOL.client &.get(env.request.resource) | ||||
|   if url = response.headers["Location"]? | ||||
|     url = URI.parse(url).full_path | ||||
|     url = URI.parse(url).request_target | ||||
|     next env.redirect url | ||||
|   end | ||||
|  | ||||
| @@ -3874,7 +3874,7 @@ error 404 do |env| | ||||
|     response = YT_POOL.client &.get("/#{item}") | ||||
|  | ||||
|     if response.status_code == 301 | ||||
|       response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).full_path) | ||||
|       response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target) | ||||
|     end | ||||
|  | ||||
|     if response.body.empty? | ||||
|   | ||||
| @@ -294,7 +294,7 @@ def template_youtube_comments(comments, locale, thin_mode) | ||||
|       end | ||||
|  | ||||
|       if !thin_mode | ||||
|         author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).full_path}" | ||||
|         author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).request_target}" | ||||
|       else | ||||
|         author_thumbnail = "" | ||||
|       end | ||||
| @@ -322,7 +322,7 @@ def template_youtube_comments(comments, locale, thin_mode) | ||||
|           html << <<-END_HTML | ||||
|           <div class="pure-g"> | ||||
|             <div class="pure-u-1 pure-u-md-1-2"> | ||||
|               <img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).full_path}"> | ||||
|               <img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).request_target}"> | ||||
|             </div> | ||||
|           </div> | ||||
|           END_HTML | ||||
| @@ -375,7 +375,7 @@ def template_youtube_comments(comments, locale, thin_mode) | ||||
|  | ||||
|       if child["creatorHeart"]? | ||||
|         if !thin_mode | ||||
|           creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).full_path}" | ||||
|           creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).request_target}" | ||||
|         else | ||||
|           creator_thumbnail = "" | ||||
|         end | ||||
| @@ -473,7 +473,7 @@ def replace_links(html) | ||||
|         params = HTTP::Params.parse(url.query.not_nil!) | ||||
|         anchor["href"] = params["q"]? | ||||
|       else | ||||
|         anchor["href"] = url.full_path | ||||
|         anchor["href"] = url.request_target | ||||
|       end | ||||
|     elsif url.to_s == "#" | ||||
|       begin | ||||
| @@ -544,7 +544,7 @@ def content_to_comment_html(content) | ||||
|           if url.path == "/redirect" | ||||
|             url = HTTP::Params.parse(url.query.not_nil!)["q"] | ||||
|           else | ||||
|             url = url.full_path | ||||
|             url = url.request_target | ||||
|           end | ||||
|         end | ||||
|  | ||||
|   | ||||
| @@ -71,14 +71,14 @@ end | ||||
| class HTTPClient < HTTP::Client | ||||
|   def set_proxy(proxy : HTTPProxy) | ||||
|     begin | ||||
|       @socket = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options) | ||||
|       @io = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options) | ||||
|     rescue IO::Error | ||||
|       @socket = nil | ||||
|       @io = nil | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def unset_proxy | ||||
|     @socket = nil | ||||
|     @io = nil | ||||
|   end | ||||
|  | ||||
|   def proxy_connection_options | ||||
|   | ||||
| @@ -329,7 +329,7 @@ def get_referer(env, fallback = "/", unroll = true) | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   referer = referer.full_path | ||||
|   referer = referer.request_target | ||||
|   referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\") | ||||
|  | ||||
|   if referer == env.request.path | ||||
|   | ||||
| @@ -60,7 +60,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob | ||||
|           elsif response.headers["Location"]?.try &.includes?("/sorry/index") | ||||
|             location = response.headers["Location"].try { |u| URI.parse(u) } | ||||
|             headers = HTTP::Headers{":authority" => location.host.not_nil!} | ||||
|             response = YT_POOL.client &.get(location.full_path, headers) | ||||
|             response = YT_POOL.client &.get(location.request_target, headers) | ||||
|  | ||||
|             html = XML.parse_html(response.body) | ||||
|             form = html.xpath_node(%(//form[@action="index"])).not_nil! | ||||
|   | ||||
| @@ -144,8 +144,8 @@ class Invidious::Routes::Embed < Invidious::Routes::BaseRoute | ||||
|     adaptive_fmts = video.adaptive_fmts | ||||
|  | ||||
|     if params.local | ||||
|       fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } | ||||
|       adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } | ||||
|       fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } | ||||
|       adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } | ||||
|     end | ||||
|  | ||||
|     video_streams = video.video_streams | ||||
|   | ||||
| @@ -255,7 +255,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute | ||||
|             traceback << "Unhandled dialog /b/0/SmsAuthInterstitial." | ||||
|           end | ||||
|  | ||||
|           login = client.get(location.full_path, headers) | ||||
|           login = client.get(location.request_target, headers) | ||||
|  | ||||
|           headers = login.cookies.add_request_headers(headers) | ||||
|           location = login.headers["Location"]?.try { |u| URI.parse(u) } | ||||
|   | ||||
| @@ -126,8 +126,8 @@ class Invidious::Routes::Watch < Invidious::Routes::BaseRoute | ||||
|     adaptive_fmts = video.adaptive_fmts | ||||
|  | ||||
|     if params.local | ||||
|       fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } | ||||
|       adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } | ||||
|       fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } | ||||
|       adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } | ||||
|     end | ||||
|  | ||||
|     video_streams = video.video_streams | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| <% if channel.banner %> | ||||
|     <div class="h-box"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>"> | ||||
|     </div> | ||||
|  | ||||
|     <div class="h-box"> | ||||
| @@ -16,7 +16,7 @@ | ||||
| <div class="pure-g h-box"> | ||||
|     <div class="pure-u-2-3"> | ||||
|         <div class="channel-profile"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>"> | ||||
|             <span><%= channel.author %></span> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| <% if channel.banner %> | ||||
|     <div class="h-box"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>"> | ||||
|     </div> | ||||
|  | ||||
|     <div class="h-box"> | ||||
| @@ -15,7 +15,7 @@ | ||||
| <div class="pure-g h-box"> | ||||
|     <div class="pure-u-2-3"> | ||||
|         <div class="channel-profile"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>"> | ||||
|             <span><%= channel.author %></span> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|             <a style="width:100%" href="/channel/<%= item.ucid %>"> | ||||
|                 <% if !env.get("preferences").as(Preferences).thin_mode %> | ||||
|                     <center> | ||||
|                         <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/> | ||||
|                         <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).request_target %>"/> | ||||
|                     </center> | ||||
|                 <% end %> | ||||
|                 <p><%= item.author %></p> | ||||
| @@ -15,7 +15,7 @@ | ||||
|             <h5><%= item.description_html %></h5> | ||||
|         <% when SearchPlaylist, InvidiousPlaylist %> | ||||
|             <% if item.id.starts_with? "RD" %> | ||||
|                 <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").full_path.split("/")[2]}" %> | ||||
|                 <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").request_target.split("/")[2]}" %> | ||||
|             <% else %> | ||||
|                 <% url = "/playlist?list=#{item.id}" %> | ||||
|             <% end %> | ||||
| @@ -23,7 +23,7 @@ | ||||
|             <a style="width:100%" href="<%= url %>"> | ||||
|                 <% if !env.get("preferences").as(Preferences).thin_mode %> | ||||
|                     <div class="thumbnail"> | ||||
|                         <img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").full_path %>"/> | ||||
|                         <img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").request_target %>"/> | ||||
|                         <p class="length"><%= number_with_separator(item.video_count) %> videos</p> | ||||
|                     </div> | ||||
|                 <% end %> | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     <% if params.video_loop %>loop<% end %> | ||||
|     <% if params.controls %>controls<% end %>> | ||||
|     <% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %> | ||||
|         <source src="<%= URI.parse(hlsvp).full_path %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream"> | ||||
|         <source src="<%= URI.parse(hlsvp).request_target %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream"> | ||||
|     <% else %> | ||||
|         <% if params.listen %> | ||||
|             <% audio_streams.each_with_index do |fmt, i| %> | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| <% if channel.banner %> | ||||
|     <div class="h-box"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>"> | ||||
|         <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>"> | ||||
|     </div> | ||||
|  | ||||
|     <div class="h-box"> | ||||
| @@ -15,7 +15,7 @@ | ||||
| <div class="pure-g h-box"> | ||||
|     <div class="pure-u-2-3"> | ||||
|         <div class="channel-profile"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>"> | ||||
|             <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>"> | ||||
|             <span><%= channel.author %></span> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -203,7 +203,7 @@ | ||||
|             <a href="/channel/<%= video.ucid %>" style="display:block;width:fit-content;width:-moz-fit-content"> | ||||
|                 <div class="channel-profile"> | ||||
|                     <% if !video.author_thumbnail.empty? %> | ||||
|                         <img src="/ggpht<%= URI.parse(video.author_thumbnail).full_path %>"> | ||||
|                         <img src="/ggpht<%= URI.parse(video.author_thumbnail).request_target %>"> | ||||
|                     <% end %> | ||||
|                     <span id="channel-name"><%= video.author %></span> | ||||
|                 </div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 TheFrenchGhosty
					TheFrenchGhosty