From 5daaaac6141bc7c9a27c5769b8b1b651d947c4b2 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Sun, 21 Apr 2024 01:23:18 -0600 Subject: [PATCH] Add the ability to explicitly load the ActiveStorage routes Fixes #31228 --- activestorage/config/routes.rb | 83 +------------------- activestorage/lib/active_storage.rb | 1 + activestorage/lib/active_storage/routes.rb | 88 ++++++++++++++++++++++ railties/test/commands/routes_test.rb | 18 ++--- 4 files changed, 99 insertions(+), 91 deletions(-) create mode 100644 activestorage/lib/active_storage/routes.rb diff --git a/activestorage/config/routes.rb b/activestorage/config/routes.rb index d890a92efc6b6..f9fc67ac498ed 100644 --- a/activestorage/config/routes.rb +++ b/activestorage/config/routes.rb @@ -1,84 +1,3 @@ # frozen_string_literal: true -Rails.application.routes.draw do - scope ActiveStorage.routes_prefix do - get "/blobs/redirect/:signed_id/*filename" => "active_storage/blobs/redirect#show", as: :rails_service_blob - get "/blobs/proxy/:signed_id/*filename" => "active_storage/blobs/proxy#show", as: :rails_service_blob_proxy - get "/blobs/:signed_id/*filename" => "active_storage/blobs/redirect#show" - - get "/representations/redirect/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show", as: :rails_blob_representation - get "/representations/proxy/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/proxy#show", as: :rails_blob_representation_proxy - get "/representations/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show" - - get "/disk/:encoded_key/*filename" => "active_storage/disk#show", as: :rails_disk_service - put "/disk/:encoded_token" => "active_storage/disk#update", as: :update_rails_disk_service - post "/direct_uploads" => "active_storage/direct_uploads#create", as: :rails_direct_uploads - end - - direct :rails_representation do |representation, options| - route_for(ActiveStorage.resolve_model_to_route, representation, options) - end - - resolve("ActiveStorage::Variant") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } - resolve("ActiveStorage::VariantWithRecord") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } - resolve("ActiveStorage::Preview") { |preview, options| route_for(ActiveStorage.resolve_model_to_route, preview, options) } - - direct :rails_blob do |blob, options| - route_for(ActiveStorage.resolve_model_to_route, blob, options) - end - - resolve("ActiveStorage::Blob") { |blob, options| route_for(ActiveStorage.resolve_model_to_route, blob, options) } - resolve("ActiveStorage::Attachment") { |attachment, options| route_for(ActiveStorage.resolve_model_to_route, attachment.blob, options) } - - direct :rails_storage_proxy do |model, options| - expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in } - expires_at = options.delete(:expires_at) - - if model.respond_to?(:signed_id) - route_for( - :rails_service_blob_proxy, - model.signed_id(expires_in: expires_in, expires_at: expires_at), - model.filename, - options - ) - else - signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at) - variation_key = model.variation.key - filename = model.blob.filename - - route_for( - :rails_blob_representation_proxy, - signed_blob_id, - variation_key, - filename, - options - ) - end - end - - direct :rails_storage_redirect do |model, options| - expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in } - expires_at = options.delete(:expires_at) - - if model.respond_to?(:signed_id) - route_for( - :rails_service_blob, - model.signed_id(expires_in: expires_in, expires_at: expires_at), - model.filename, - options - ) - else - signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at) - variation_key = model.variation.key - filename = model.blob.filename - - route_for( - :rails_blob_representation, - signed_blob_id, - variation_key, - filename, - options - ) - end - end -end if ActiveStorage.draw_routes +Rails.application.routes.draw { ActiveStorage::Routes.apply(self) } if ActiveStorage.draw_routes diff --git a/activestorage/lib/active_storage.rb b/activestorage/lib/active_storage.rb index e1687dc1c7b13..9467bc8462159 100644 --- a/activestorage/lib/active_storage.rb +++ b/activestorage/lib/active_storage.rb @@ -28,6 +28,7 @@ require "active_support/rails" require "active_support/core_ext/numeric/time" +require "active_storage/routes" require "active_storage/version" require "active_storage/deprecator" require "active_storage/errors" diff --git a/activestorage/lib/active_storage/routes.rb b/activestorage/lib/active_storage/routes.rb new file mode 100644 index 0000000000000..1cb4af8f89878 --- /dev/null +++ b/activestorage/lib/active_storage/routes.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module ActiveStorage + module Routes + def self.apply(router) + router.scope ActiveStorage.routes_prefix do + router.get "/blobs/redirect/:signed_id/*filename" => "active_storage/blobs/redirect#show", as: :rails_service_blob + router.get "/blobs/proxy/:signed_id/*filename" => "active_storage/blobs/proxy#show", as: :rails_service_blob_proxy + router.get "/blobs/:signed_id/*filename" => "active_storage/blobs/redirect#show" + + router.get "/representations/redirect/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show", as: :rails_blob_representation + router.get "/representations/proxy/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/proxy#show", as: :rails_blob_representation_proxy + router.get "/representations/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show" + + router.get "/disk/:encoded_key/*filename" => "active_storage/disk#show", as: :rails_disk_service + router.put "/disk/:encoded_token" => "active_storage/disk#update", as: :update_rails_disk_service + router.post "/direct_uploads" => "active_storage/direct_uploads#create", as: :rails_direct_uploads + end + + router.direct :rails_representation do |representation, options| + route_for(ActiveStorage.resolve_model_to_route, representation, options) + end + + router.resolve("ActiveStorage::Variant") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } + router.resolve("ActiveStorage::VariantWithRecord") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } + router.resolve("ActiveStorage::Preview") { |preview, options| route_for(ActiveStorage.resolve_model_to_route, preview, options) } + + router.direct :rails_blob do |blob, options| + route_for(ActiveStorage.resolve_model_to_route, blob, options) + end + + router.resolve("ActiveStorage::Blob") { |blob, options| route_for(ActiveStorage.resolve_model_to_route, blob, options) } + router.resolve("ActiveStorage::Attachment") { |attachment, options| route_for(ActiveStorage.resolve_model_to_route, attachment.blob, options) } + + router.direct :rails_storage_proxy do |model, options| + expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in } + expires_at = options.delete(:expires_at) + + if model.respond_to?(:signed_id) + route_for( + :rails_service_blob_proxy, + model.signed_id(expires_in: expires_in, expires_at: expires_at), + model.filename, + options + ) + else + signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at) + variation_key = model.variation.key + filename = model.blob.filename + + route_for( + :rails_blob_representation_proxy, + signed_blob_id, + variation_key, + filename, + options + ) + end + end + + router.direct :rails_storage_redirect do |model, options| + expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in } + expires_at = options.delete(:expires_at) + + if model.respond_to?(:signed_id) + route_for( + :rails_service_blob, + model.signed_id(expires_in: expires_in, expires_at: expires_at), + model.filename, + options + ) + else + signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at) + variation_key = model.variation.key + filename = model.blob.filename + + route_for( + :rails_blob_representation, + signed_blob_id, + variation_key, + filename, + options + ) + end + end + end + end +end diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb index 58ccad151681b..4404cd718170f 100644 --- a/railties/test/commands/routes_test.rb +++ b/railties/test/commands/routes_test.rb @@ -340,55 +340,55 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase Verb | GET URI | /rails/active_storage/blobs/redirect/:signed_id/*filename(.:format) Controller#Action | active_storage/blobs/redirect#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:5 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:7 --[ Route 17 ]------------- Prefix | rails_service_blob_proxy Verb | GET URI | /rails/active_storage/blobs/proxy/:signed_id/*filename(.:format) Controller#Action | active_storage/blobs/proxy#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:6 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:8 --[ Route 18 ]------------- Prefix |#{" "} Verb | GET URI | /rails/active_storage/blobs/:signed_id/*filename(.:format) Controller#Action | active_storage/blobs/redirect#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:7 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:9 --[ Route 19 ]------------- Prefix | rails_blob_representation Verb | GET URI | /rails/active_storage/representations/redirect/:signed_blob_id/:variation_key/*filename(.:format) Controller#Action | active_storage/representations/redirect#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:9 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:11 --[ Route 20 ]------------- Prefix | rails_blob_representation_proxy Verb | GET URI | /rails/active_storage/representations/proxy/:signed_blob_id/:variation_key/*filename(.:format) Controller#Action | active_storage/representations/proxy#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:10 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:12 --[ Route 21 ]------------- Prefix |#{" "} Verb | GET URI | /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) Controller#Action | active_storage/representations/redirect#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:11 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:13 --[ Route 22 ]------------- Prefix | rails_disk_service Verb | GET URI | /rails/active_storage/disk/:encoded_key/*filename(.:format) Controller#Action | active_storage/disk#show - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:13 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:15 --[ Route 23 ]------------- Prefix | update_rails_disk_service Verb | PUT URI | /rails/active_storage/disk/:encoded_token(.:format) Controller#Action | active_storage/disk#update - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:14 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:16 --[ Route 24 ]------------- Prefix | rails_direct_uploads Verb | POST URI | /rails/active_storage/direct_uploads(.:format) Controller#Action | active_storage/direct_uploads#create - Source Location | #{rails_gem_root}/activestorage/config/routes.rb:15 + Source Location | #{rails_gem_root}/activestorage/lib/active_storage/routes.rb:17 MESSAGE end