Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active storage add proxying #34477

Merged
Show file tree
Hide file tree
Changes from 155 commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
d0b1280
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Nov 3, 2018
177574f
Basic redirects and proxying is working on the model level.
fleck Nov 5, 2018
31a2d2a
Proxying variants is working.
fleck Nov 8, 2018
09f37c3
Fix preview.
fleck Nov 8, 2018
39eb31a
Working on previews.
fleck Nov 8, 2018
71b499e
Should fix errors with previews not streaming.
fleck Nov 14, 2018
7c00122
Move delivery logic to method.
fleck Nov 15, 2018
96b54a7
change delivery method default and add support for direct.
fleck Nov 17, 2018
0b488cc
Fix blob route.
fleck Nov 17, 2018
5281255
Accidentally removed blob resolver, re add it.
fleck Nov 17, 2018
4dd0e2f
Basic redirects and proxying is working on the model level.
fleck Nov 5, 2018
0db8f77
Proxying variants is working.
fleck Nov 8, 2018
813b8e0
Fix preview.
fleck Nov 8, 2018
ca72a7e
Working on previews.
fleck Nov 8, 2018
73f2202
Should fix errors with previews not streaming.
fleck Nov 14, 2018
8ee4bfb
Move delivery logic to method.
fleck Nov 15, 2018
3a1bc1d
change delivery method default and add support for direct.
fleck Nov 17, 2018
61d228d
Fix blob route.
fleck Nov 17, 2018
c82b288
Accidentally removed blob resolver, re add it.
fleck Nov 17, 2018
0f621c8
Merge branch 'active-storage-add-proxying-and-direct-downloads' of gi…
fleck Nov 17, 2018
9e34b40
Remove extra comment.
fleck Nov 17, 2018
25429de
Explain variant and preview.
fleck Nov 17, 2018
a55f88f
don't use 'its'
fleck Nov 17, 2018
f5586e2
Fix disposition and content type.
fleck Nov 17, 2018
f016113
Add delivery method to has_many_attached.
fleck Nov 17, 2018
46f110e
Get service_url from processed not blob.
fleck Nov 17, 2018
3ae4936
Fix code climate issues.
fleck Nov 17, 2018
464ed95
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Dec 4, 2018
2d2fb66
Add model instance method overrides.
fleck Dec 4, 2018
f0c7723
Fix code climate issues and give blob method path option.
fleck Dec 4, 2018
331ed77
Merge branch 'master' of https://github.com/rails/rails
fleck Dec 9, 2018
c271ee6
Merge branch 'master' of https://github.com/rails/rails
fleck Dec 16, 2018
9aed641
Merge branch 'master' of https://github.com/rails/rails
fleck Dec 24, 2018
e83edfb
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Dec 24, 2018
da1df76
Make proxied assets public.
fleck Dec 25, 2018
fe0ff8f
Add documentation.
fleck Dec 29, 2018
9676f88
Merge branch 'master' of https://github.com/rails/rails
fleck Dec 30, 2018
b31bb85
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Dec 30, 2018
97ebfaf
Added test for blobs controller to verify correct caching.
fleck Jan 1, 2019
969a1ed
Test representation proxy cache control headers.
fleck Jan 1, 2019
ec254dd
Test global proxying option.
fleck Jan 12, 2019
017e8ae
Add test for deliver method on blob.
fleck Jan 13, 2019
b932f1b
Test delivery on variants.
fleck Jan 13, 2019
80db667
Change range for comparison.
fleck Jan 13, 2019
7bfb8b2
Fixed bug with model delivery setting.
fleck Jan 14, 2019
3d76291
Update configuration test.
fleck Jan 14, 2019
66a4a20
Update routes test.
fleck Jan 14, 2019
93fbf27
Dry up routes.
fleck Jan 15, 2019
13ac0f4
Change parameter name.
fleck Jan 15, 2019
1483c17
Add tests for delivery method on model.
fleck Jan 15, 2019
6ef2c7e
Test preview methods.
fleck Jan 15, 2019
18deb51
Clean up delivery method test.
fleck Jan 15, 2019
24244d7
Add test for preview.
fleck Jan 15, 2019
0cea5a0
Merge branch 'master' of https://github.com/rails/rails
fleck Jan 15, 2019
ba02d81
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Jan 15, 2019
da0084c
Fix code climate issues.
fleck Jan 15, 2019
7056d6a
Fix routes_prefix railtie test.
fleck Jan 16, 2019
cec9b0d
Fixed rake routes railtie test.
fleck Jan 16, 2019
72edc1c
Redo backticks in test name.
fleck Jan 16, 2019
93808b7
Updating another routes test.
fleck Jan 16, 2019
ddbe958
Update last rails routes test.
fleck Jan 16, 2019
8ddfa55
Merge branch 'master' of https://github.com/rails/rails
fleck Mar 31, 2019
3d34726
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Mar 31, 2019
16e1641
Merge branch 'master' of https://github.com/rails/rails
fleck Mar 31, 2019
aa6cdf0
Merge branch 'master' of https://github.com/rails/rails
fleck Apr 7, 2019
69fa76a
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Apr 7, 2019
c53b4e6
Remove direct delivery method.
fleck Apr 7, 2019
7fb06f1
Remove tests for direct delivery.
fleck Apr 7, 2019
d6e69e9
Update attachments reflection test.
fleck Apr 7, 2019
a9b249a
Remove dependent reflection.
fleck Apr 7, 2019
a3c2882
Merge branch 'master' of https://github.com/rails/rails
fleck Apr 7, 2019
a335e3b
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Apr 7, 2019
e7979b6
Remove direct from overview.
fleck Apr 8, 2019
290453a
Merge branch 'master' of https://github.com/rails/rails
fleck Apr 27, 2019
4faafc0
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Apr 27, 2019
22645e7
Add support for changing host.
fleck May 13, 2019
1e758f3
Merge branch 'master' of https://github.com/rails/rails
fleck May 13, 2019
1abfd9a
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck May 13, 2019
1dc2188
Refactor logic out of routes and into class
fleck May 29, 2019
cc8d0c3
Fix code climate issues.
fleck May 29, 2019
486b0bc
Merge branch 'master' of https://github.com/rails/rails
fleck Jun 1, 2019
f84e086
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Jun 1, 2019
06693d4
Clean up some edge cases and add test.
fleck Jun 1, 2019
baa1929
Update docs.
fleck Jun 1, 2019
6ce1f1b
Clean up extra curly braces
fleck Jun 1, 2019
73639b8
Proxy delivery method is working
fleck Jul 27, 2019
64d6a28
Move url options method.
fleck Jul 29, 2019
86131e3
Merge branch 'master' of https://github.com/rails/rails
fleck Jul 29, 2019
7c23631
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Jul 29, 2019
7660a4f
code climate fixes.
fleck Jul 29, 2019
6c1d003
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Aug 3, 2019
21b29bc
Move URL options to each class.
fleck Aug 5, 2019
521244f
simply registering delivery method.
fleck Aug 19, 2019
eacde0f
Variants are working for has_one
fleck Aug 20, 2019
e772d75
Less nils
fleck Aug 20, 2019
d117ab9
Fix model level setting.
fleck Aug 22, 2019
302923a
Cleaning up tests to use .url
fleck Aug 22, 2019
fb397b2
Can't set cache control per instance
fleck Aug 22, 2019
acf951a
Fix expire time
fleck Aug 22, 2019
9b7ca2c
Merge branch 'master' into active-storage-add-proxying-and-direct-dow…
fleck Aug 30, 2019
71d8a2c
Split up config
fleck Oct 1, 2019
32d604c
Add docs for cdn.
fleck Oct 1, 2019
2f15573
Remove cloudflare from docs.
fleck Oct 1, 2019
f35423b
Clean up host docs.
fleck Oct 1, 2019
cc545d6
Updating overview.
fleck Oct 1, 2019
bcb5ffe
Update configuration.
fleck Oct 1, 2019
bdd0f80
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Oct 1, 2019
eb64ff0
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Oct 2, 2019
d09134c
Update docs and engine.
fleck Oct 16, 2019
c8c67ba
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Oct 16, 2019
68a36ad
Fix method name.
fleck Oct 16, 2019
5930a22
Fix config test.
fleck Oct 16, 2019
1938c82
Update to new method in tests.
fleck Oct 16, 2019
fbaaca9
days is more readable.
fleck Oct 21, 2019
68f9816
simplifying
fleck Nov 6, 2019
e717e69
Use days for proxy_urls_expire_in
fleck Nov 6, 2019
bd19891
Moving header logic to concern, removing extra delivery_methods
fleck Nov 6, 2019
1207c3c
Remove dup routes_prefix
fleck Nov 6, 2019
ba1f16f
Remove model delivery_method from test.
fleck Nov 6, 2019
7819297
set headers in concern.
fleck Nov 6, 2019
4accc9d
Cleanup routes.
fleck Nov 19, 2019
2003663
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Nov 19, 2019
f4044b8
Fix typo.
fleck Nov 28, 2019
f67a4bc
use same convention for routes.
fleck Nov 28, 2019
4bd8f5f
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Dec 16, 2019
1927754
move url call to the model.
fleck Dec 28, 2019
99386a3
Cleanup old implementation
fleck Dec 28, 2019
366ab0b
Remove extra settings.
fleck Dec 28, 2019
975571e
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Mar 11, 2020
2817a38
Remove methods from model.
fleck Mar 11, 2020
c07d9ad
Add direct route for proxy
fleck Mar 14, 2020
c9342c7
same API for blobs and representations
fleck Mar 15, 2020
dc84bdd
split routes
fleck Apr 1, 2020
a147010
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Apr 1, 2020
e698761
Set expire in controller.
fleck Apr 1, 2020
387baf3
Start cleaning up tests.
fleck Apr 1, 2020
c08951d
Allow custom resolve name
fleck Apr 8, 2020
293553d
Update docs.
fleck Apr 8, 2020
c8fc088
tweak
fleck Apr 8, 2020
108e344
Update config readme.
fleck Apr 8, 2020
e4eba43
typo
fleck Apr 8, 2020
491b4d5
Revert model test.
fleck Apr 8, 2020
b7cc8c7
Revert old test changes.
fleck Apr 8, 2020
6d732d2
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Apr 8, 2020
176edc7
Update expanded routes.
fleck Apr 8, 2020
3e79f37
Fix routes -g show
fleck Apr 8, 2020
69260a8
Fix another route test.
fleck Apr 8, 2020
7d2ad32
Update config test.
fleck Apr 8, 2020
b09f350
fix rake route test.
fleck Apr 8, 2020
ea0bda8
change config name
fleck Apr 9, 2020
9ff39ac
Update routes in test.
fleck Apr 9, 2020
2885507
Update form helper test.
fleck Apr 9, 2020
dec20c4
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck Apr 9, 2020
517d984
Fix bug with proxying previews, add tests
fleck Apr 20, 2020
3d681a9
Fix spacing in engine.
fleck Apr 20, 2020
6d99bd7
Merge branch 'master' of https://github.com/rails/rails into active-s…
fleck May 10, 2020
824c703
Update readme
fleck May 10, 2020
a84d081
Use cache forever method.
fleck May 10, 2020
b787c96
Rename method.
fleck May 10, 2020
aea29e9
Update key methods
fleck May 10, 2020
d375962
extract stream method
fleck May 10, 2020
395e0b3
Document controllers.
fleck May 10, 2020
a7dc7dd
appease rubocop
fleck May 10, 2020
d3a6ba7
Use the block form of http_cache_forever
georgeclaghorn May 11, 2020
178260c
Split tests by controller
georgeclaghorn May 11, 2020
4d14661
Tweak controller names: redirection → redirect
georgeclaghorn May 11, 2020
49027c6
Add CHANGELOG entry
georgeclaghorn May 11, 2020
7558486
Tweak README [ci skip]
georgeclaghorn May 11, 2020
3ee6b44
Update Railties tests for new controller names
georgeclaghorn May 11, 2020
ed22fd4
Update configuring guide [ci skip]
georgeclaghorn May 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions actiontext/test/template/form_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[content]" id="message_content_trix_input_message" />' \
'<trix-editor id="message_content" input="message_content_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor id="message_content" input="message_content_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand All @@ -47,7 +47,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[content]" id="message_content_trix_input_message" />' \
'<trix-editor id="message_content" input="message_content_trix_input_message" class="custom-class" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor id="message_content" input="message_content_trix_input_message" class="custom-class" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand All @@ -61,7 +61,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[not_an_attribute]" id="message_not_an_attribute_trix_input_message" />' \
'<trix-editor id="message_not_an_attribute" input="message_not_an_attribute_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor id="message_not_an_attribute" input="message_not_an_attribute_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand All @@ -75,7 +75,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[content]" id="trix_input_1" />' \
'<trix-editor id="message_content" input="trix_input_1" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor id="message_content" input="trix_input_1" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand All @@ -89,7 +89,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[content]" id="message_content_trix_input_message" />' \
'<trix-editor placeholder="Content" id="message_content" input="message_content_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor placeholder="Content" id="message_content" input="message_content_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand All @@ -105,7 +105,7 @@ def form_with(*, **)
assert_dom_equal \
'<form action="/messages" accept-charset="UTF-8" data-remote="true" method="post">' \
'<input type="hidden" name="message[title]" id="message_title_trix_input_message" />' \
'<trix-editor placeholder="Story title" id="message_title" input="message_title_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename">' \
'<trix-editor placeholder="Story title" id="message_title" input="message_title_trix_input_message" class="trix-content" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename">' \
"</trix-editor>" \
"</form>",
output_buffer
Expand Down
19 changes: 19 additions & 0 deletions activestorage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,25 @@ Variation of image attachment:
<%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %>
```

## Delivery Routes
Active storage provides two primary ways to route assets.
fleck marked this conversation as resolved.
Show resolved Hide resolved

### Redirect (default)
`:rails_storage_redirect` Requests for files will redirect to a temporary service URL.

### Proxy
`:rails_storage_proxy` Files are proxied through the application server. Useful for serving assets from a CDN or HTML caching.

### Changing the default resolver
To make all assets cachable via a CDN you may change the default resolver for Active Storage models:
```ruby
config.active_storage.resolve_model_to_route = :rails_storage_proxy
```
If a more granular approach is needed the path or url helpers may be called from your views:
```ruby
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
```

## Direct uploads

Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

# Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download.
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
# security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own
# authenticated redirection controller.
fleck marked this conversation as resolved.
Show resolved Hide resolved
class ActiveStorage::Blobs::ProxyController < ActiveStorage::BaseController
include ActiveStorage::SetBlob
include ActiveStorage::SetHeaders

def show
set_headers(@blob)

@blob.download do |chunk|
response.stream.write(chunk)
end
ensure
response.stream.close
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
# security-through-obscurity factor of the signed blob references, you'll need to implement your own
# authenticated redirection controller.
class ActiveStorage::BlobsController < ActiveStorage::BaseController
class ActiveStorage::Blobs::RedirectionController < ActiveStorage::BaseController
include ActiveStorage::SetBlob

def show
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class ActiveStorage::Representations::ProxyController < ActiveStorage::BaseController
fleck marked this conversation as resolved.
Show resolved Hide resolved
include ActiveStorage::SetBlob
include ActiveStorage::SetHeaders

def show
representation = @blob.representation(params[:variation_key]).processed

set_headers(representation.image.blob)

@blob.service.download(representation.key) do |chunk|
response.stream.write(chunk)
end
ensure
response.stream.close
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
# security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own
# authenticated redirection controller.
class ActiveStorage::RepresentationsController < ActiveStorage::BaseController
class ActiveStorage::Representations::RedirectionController < ActiveStorage::BaseController
include ActiveStorage::SetBlob

def show
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module ActiveStorage::SetHeaders #:nodoc:
extend ActiveSupport::Concern

private
def set_headers(blob)
expires_in 1.year, public: true
fleck marked this conversation as resolved.
Show resolved Hide resolved

response.headers["Content-Type"] = blob.content_type
response.headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(
disposition: params[:disposition] || "inline",
filename: blob.filename.sanitized
)
end
fleck marked this conversation as resolved.
Show resolved Hide resolved
end
6 changes: 6 additions & 0 deletions activestorage/app/models/active_storage/preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ def url(**options)
end
end

# Returns a combination key of the blob and the variation that together identifies a specific variant.
def key
variant
"variants/#{image.key}/#{Digest::SHA256.hexdigest(variation.key)}"
end
fleck marked this conversation as resolved.
Show resolved Hide resolved

alias_method :service_url, :url
deprecate service_url: :url

Expand Down
63 changes: 55 additions & 8 deletions activestorage/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

Rails.application.routes.draw do
scope ActiveStorage.routes_prefix do
get "/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob
get "/blobs/redirect/:signed_id/*filename" => "active_storage/blobs/redirection#show", as: :rails_service_blob
get "/blobs/proxy/:signed_id/*filename" => "active_storage/blobs/proxy#show", as: :rails_service_blob_proxy

get "/representations/:signed_blob_id/:variation_key/*filename" => "active_storage/representations#show", as: :rails_blob_representation
get "/representations/redirect/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirection#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 "/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
Expand All @@ -19,15 +21,60 @@
route_for(:rails_blob_representation, signed_blob_id, variation_key, filename, options)
end

resolve("ActiveStorage::Variant") { |variant, options| route_for(:rails_representation, variant, options) }
resolve("ActiveStorage::VariantWithRecord") { |variant, options| route_for(:rails_representation, variant, options) }
resolve("ActiveStorage::Preview") { |preview, options| route_for(:rails_representation, preview, options) }

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(:rails_service_blob, blob.signed_id, blob.filename, options)
end

resolve("ActiveStorage::Blob") { |blob, options| route_for(:rails_blob, blob, options) }
resolve("ActiveStorage::Attachment") { |attachment, options| route_for(:rails_blob, attachment.blob, options) }
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|
if model.respond_to?(:signed_id)
route_for(
:rails_service_blob_proxy,
model.signed_id,
model.filename,
options
)
else
signed_blob_id = model.blob.signed_id
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|
if model.respond_to?(:signed_id)
route_for(
:rails_service_blob,
model.signed_id,
model.filename,
options
)
else
signed_blob_id = model.blob.signed_id
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
1 change: 1 addition & 0 deletions activestorage/lib/active_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ module ActiveStorage

mattr_accessor :routes_prefix, default: "/rails/active_storage"
mattr_accessor :draw_routes, default: true
mattr_accessor :resolve_model_to_route, default: :rails_storage_redirect

mattr_accessor :replace_on_assign_to_many, default: false
mattr_accessor :track_variants, default: false
Expand Down
1 change: 1 addition & 0 deletions activestorage/lib/active_storage/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class Engine < Rails::Engine # :nodoc:
ActiveStorage.paths = app.config.active_storage.paths || {}
ActiveStorage.routes_prefix = app.config.active_storage.routes_prefix || "/rails/active_storage"
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect

ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
Expand Down
7 changes: 7 additions & 0 deletions activestorage/test/controllers/blobs_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ class ActiveStorage::BlobsControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to(/racecar\.jpg/)
assert_equal "max-age=300, private", @response.headers["Cache-Control"]
end

test "proxying responds with long max-age" do
get rails_storage_proxy_url(@blob)

assert_response(:success)
assert_equal "max-age=31556952, public", @response.headers["Cache-Control"]
end
end
12 changes: 12 additions & 0 deletions activestorage/test/controllers/representations_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class ActiveStorage::RepresentationsControllerWithVariantsTest < ActionDispatch:

assert_response :not_found
end

test "proxying variant" do
get rails_storage_proxy_url(@blob.variant(resize: "100x100"))

assert_response(:success)
end
end

class ActiveStorage::RepresentationsControllerWithPreviewsTest < ActionDispatch::IntegrationTest
Expand All @@ -54,6 +60,12 @@ class ActiveStorage::RepresentationsControllerWithPreviewsTest < ActionDispatch:
assert_equal 100, image.height
end

test "proxying preview" do
get rails_storage_proxy_url(@blob.preview(resize: "100x100"))

assert_response(:success)
end

test "showing preview with invalid signed blob ID" do
get rails_blob_representation_url(
filename: @blob.filename,
Expand Down
10 changes: 10 additions & 0 deletions guides/source/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,16 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla

* `config.active_storage.draw_routes` can be used to toggle Active Storage route generation. The default is `true`.

* `config.active_storage.resolve_model_to_route` can be used to globally change how Active Storage files are delivered.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#40920 should fix it


```ruby
config.active_storage.resolve_name = :rails_storage_proxy
```

The default is `:rails_storage_redirect`.
* `:rails_storage_redirect` - Redirect files to temporary service URL.
* `:rails_storage_proxy` - Proxy assets through rails.

### Results of `config.load_defaults`

`config.load_defaults` sets new defaults up to and including the version passed. Such that passing, say, '6.0' also gets the new defaults from every version before it.
Expand Down
14 changes: 8 additions & 6 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2562,12 +2562,14 @@ class MyLogger < ::Logger

output = rails("routes", "-g", "active_storage")
assert_equal <<~MESSAGE, output
Prefix Verb URI Pattern Controller#Action
rails_service_blob GET /files/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /files/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /files/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /files/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /files/direct_uploads(.:format) active_storage/direct_uploads#create
Prefix Verb URI Pattern Controller#Action
rails_service_blob GET /files/blobs/redirect/:signed_id/*filename(.:format) active_storage/blobs/redirection#show
rails_service_blob_proxy GET /files/blobs/proxy/:signed_id/*filename(.:format) active_storage/blobs/proxy#show
rails_blob_representation GET /files/representations/redirect/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/redirection#show
rails_blob_representation_proxy GET /files/representations/proxy/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/proxy#show
rails_disk_service GET /files/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /files/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /files/direct_uploads(.:format) active_storage/direct_uploads#create
MESSAGE
end

Expand Down