Skip to content

Commit ab8e3d2

Browse files
author
David Heinemeier Hansson
authored
Extract ActiveStorage::Streaming so your own controllers can use it (rails#41440)
Extract ActiveStorage::Streaming so your own controller can use it
1 parent ee7cf8c commit ab8e3d2

File tree

8 files changed

+42
-32
lines changed

8 files changed

+42
-32
lines changed

.rubocop.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ Layout/EmptyLinesAroundModuleBody:
8989
Style/HashSyntax:
9090
Enabled: true
9191

92-
Layout/FirstArgumentIndentation:
93-
Enabled: true
94-
9592
# Method definitions after `private` or `protected` isolated calls need one
9693
# extra level of indentation.
9794
Layout/IndentationConsistency:

activestorage/CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
* Add `ActiveStorage::Streaming` module that can be included in a controller to get access to `#send_blob_stream`,
2+
which wraps the new `ActionController::Base#send_stream` method to stream a blob from cloud storage:
3+
4+
```ruby
5+
class MyPublicBlobsController < ApplicationController
6+
include ActiveStorage::SetBlob, ActiveStorage::Streaming
7+
8+
def show
9+
http_cache_forever(public: true) do
10+
send_blob_stream @blob, disposition: params[:disposition]
11+
end
12+
end
13+
end
14+
```
15+
16+
*DHH*
17+
118
* Add ability to use pre-defined variants.
219

320
```ruby

activestorage/app/controllers/active_storage/base_controller.rb

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,9 @@
22

33
# The base class for all Active Storage controllers.
44
class ActiveStorage::BaseController < ActionController::Base
5-
include ActiveStorage::SetCurrent
5+
include ActiveStorage::SetCurrent, ActiveStorage::Streaming
66

77
protect_from_forgery with: :exception
88

99
self.etag_with_template_digest = false
10-
11-
private
12-
def stream(blob)
13-
blob.download do |chunk|
14-
response.stream.write chunk
15-
end
16-
ensure
17-
response.stream.close
18-
end
1910
end

activestorage/app/controllers/active_storage/blobs/proxy_controller.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
# Proxy files through application. This avoids having a redirect and makes files easier to cache.
44
class ActiveStorage::Blobs::ProxyController < ActiveStorage::BaseController
55
include ActiveStorage::SetBlob
6-
include ActiveStorage::SetHeaders
76

87
def show
98
http_cache_forever public: true do
10-
set_content_headers_from @blob
11-
stream @blob
9+
send_blob_stream @blob
1210
end
1311
end
1412
end

activestorage/app/controllers/active_storage/representations/proxy_controller.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
# Proxy files through application. This avoids having a redirect and makes files easier to cache.
44
class ActiveStorage::Representations::ProxyController < ActiveStorage::BaseController
55
include ActiveStorage::SetBlob
6-
include ActiveStorage::SetHeaders
76

87
def show
98
http_cache_forever public: true do
10-
set_content_headers_from representation.image
11-
stream representation
9+
send_blob_stream representation.image
1210
end
1311
end
1412

activestorage/app/controllers/concerns/active_storage/set_headers.rb

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
module ActiveStorage::Streaming
4+
DEFAULT_BLOB_STREAMING_DISPOSITION = "inline"
5+
6+
include ActionController::Live
7+
8+
private
9+
# Stream the blob from storage directly to the response. The disposition can be controlled by setting +disposition+.
10+
# The content type and filename is set directly from the +blob+.
11+
def send_blob_stream(blob, disposition: nil) #:doc:
12+
send_stream(
13+
filename: blob.filename.sanitized,
14+
disposition: blob.forced_disposition_for_serving || disposition || DEFAULT_BLOB_STREAMING_DISPOSITION,
15+
type: blob.content_type_for_serving) do |stream|
16+
blob.download do |chunk|
17+
stream.write chunk
18+
end
19+
end
20+
end
21+
end

activestorage/test/controllers/representations/proxy_controller_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ActiveStorage::Representations::ProxyControllerWithPreviewsTest < ActionDi
4848

4949
assert_predicate @blob.preview_image, :attached?
5050

51-
image = read_image(@blob.preview_image.variant(resize: "100x100"))
51+
image = read_image(@blob.preview_image.variant(resize: "100x100").processed)
5252
assert_equal 77, image.width
5353
assert_equal 100, image.height
5454
end

0 commit comments

Comments
 (0)