WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/ext/kemal_static_file_handler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,13 @@ module Kemal
end
end
end

# See https://github.com/crystal-lang/crystal/issues/15788
#
# URL fragments also aren't passed along but there isn't an easy way
# to retrieve that at the moment.
private def redirect_to(context, path)
context.response.redirect URI.new(path: URI.encode_path(path.to_s), query: context.request.query)
end
end
end
25 changes: 24 additions & 1 deletion src/invidious/helpers/handlers.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,30 @@ class Kemal::ExceptionHandler

private def call_exception_with_status_code(context : HTTP::Server::Context, exception : Exception, status_code : Int32)
return if context.response.closed?
return if exclude_match? context

# Invidious excludes the status code error handlers from running on the api routes
# meaning that we are unable to redirect /api/v1/storyboards/sb/... to the right location
# within a 404 handler. As a quick fix we'll match it here.
#
# For future reference this is also why the API will always return a 200 status code
# even when a route could not be found.
#
# TODO: In the future there should be dedicated status code error handlers for the api.
#
if exclude_match?(context)
if status_code == 404
# Only necessary on Crystal versions >= 1.16.0
{% if compare_versions(Crystal::VERSION, "1.16.0") >= 0 %}
if HOST_URL.empty? && context.request.path.starts_with?("/api/v1/storyboards/sb")
return context.redirect "#{context.request.path[19..]}?#{context.params.query}", status_code: 302
end

return
{% end %}
end

return
end

if !Kemal.config.error_handlers.empty? && Kemal.config.error_handlers.has_key?(status_code)
context.response.content_type = "text/html" unless context.response.headers.has_key?("Content-Type")
Expand Down
19 changes: 15 additions & 4 deletions src/invidious/routes/errors.cr
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
module Invidious::Routes::ErrorRoutes
def self.error_404(env)
# Workaround for #3117
if HOST_URL.empty? && env.request.path.starts_with?("/v1/storyboards/sb")
return env.redirect "#{env.request.path[15..]}?#{env.params.query}"
end
# Workaround for #3117 on versions prior to 1.16.0
#
# Crystal 1.16.0 fixed the parsing of some weird-looking paths
# meaning that `//api/v1/storyboards/sb/i/...` will no longer
# get parsed into a request target of `/v1/storyboards/sb/i/...`
#
# This also means that we won't be able to handle the logic here
# because status code error handles are disabled for the API routes

# We only need to include this workaround on versions prior to 1.16.0
{% if compare_versions(Crystal::VERSION, "1.16.0") < 0 %}
if HOST_URL.empty? && env.request.path.starts_with?("/v1/storyboards/sb")
return env.redirect "#{env.request.path[15..]}?#{env.params.query}"
end
{% end %}

if md = env.request.path.match(/^\/(?<id>([a-zA-Z0-9_-]{11})|(\w+))$/)
item = md["id"]
Expand Down
Loading