Use a dedicated endpoind for downloads

This allows us to not pass file name ("title") in the form
data and to enforce some sanity checks
This commit is contained in:
Samantaz Fox
2022-02-22 18:11:11 +01:00
parent fe057c7873
commit 2f335b3d2c
5 changed files with 82 additions and 31 deletions

View File

@@ -289,4 +289,52 @@ module Invidious::Routes::Watch
return error_template(404, "The requested clip doesn't exist")
end
end
def self.download(env)
if CONFIG.disabled?("downloads")
return error_template(403, "Administrator has disabled this endpoint.")
end
title = env.params.body["title"]? || ""
video_id = env.params.body["id"]? || ""
selection = env.params.body["download_widget"]?
if title.empty? || video_id.empty? || selection.nil?
return error_template(400, "Missing form data")
end
download_widget = JSON.parse(selection)
extension = download_widget["ext"].as_s
filename = URI.encode_www_form(
"#{video_id}-#{title}.#{extension}",
space_to_plus: false
)
# Pass form parameters as URL parameters for the handlers of both
# /latest_version and /api/v1/captions. This avoids an un-necessary
# redirect and duplicated (and hazardous) sanity checks.
env.params.query["id"] = video_id
env.params.query["title"] = filename
# Delete the useless ones
env.params.body.delete("id")
env.params.body.delete("title")
env.params.body.delete("download_widget")
if label = download_widget["label"]?
# URL params specific to /api/v1/captions/:id
env.params.query["label"] = URI.encode_www_form(label.as_s, space_to_plus: false)
return Invidious::Routes::API::V1::Videos.captions(env)
elsif itag = download_widget["itag"]?.try &.as_i
# URL params specific to /latest_version
env.params.query["itag"] = itag.to_s
env.params.query["local"] = "true"
return Invidious::Routes::VideoPlayback.latest_version(env)
else
return error_template(400, "Invalid label or itag")
end
end
end