aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage/app
diff options
context:
space:
mode:
authorGeorge Claghorn <george@basecamp.com>2018-07-15 19:58:14 -0400
committerGeorge Claghorn <george@basecamp.com>2018-07-15 19:58:14 -0400
commit390097531bd17369f05a23eba58c37b850ac95dd (patch)
treeb2dfaf535680ae6ff94c6fb7ed441b1d348e397a /activestorage/app
parent5a71a773eab626319d30f35402b9595a26bfe64e (diff)
downloadrails-390097531bd17369f05a23eba58c37b850ac95dd.tar.gz
rails-390097531bd17369f05a23eba58c37b850ac95dd.tar.bz2
rails-390097531bd17369f05a23eba58c37b850ac95dd.zip
Support HTTP Range downloads from disk
Closes #32193.
Diffstat (limited to 'activestorage/app')
-rw-r--r--activestorage/app/controllers/active_storage/disk_controller.rb29
1 files changed, 15 insertions, 14 deletions
diff --git a/activestorage/app/controllers/active_storage/disk_controller.rb b/activestorage/app/controllers/active_storage/disk_controller.rb
index 63918eb6f4..436cd0ccd8 100644
--- a/activestorage/app/controllers/active_storage/disk_controller.rb
+++ b/activestorage/app/controllers/active_storage/disk_controller.rb
@@ -5,23 +5,14 @@
# Always go through the BlobsController, or your own authenticated controller, rather than directly
# to the service url.
class ActiveStorage::DiskController < ActiveStorage::BaseController
- include ActionController::Live
-
skip_forgery_protection
def show
if key = decode_verified_key
- response.headers["Content-Type"] = params[:content_type] || DEFAULT_SEND_FILE_TYPE
- response.headers["Content-Disposition"] = params[:disposition] || DEFAULT_SEND_FILE_DISPOSITION
-
- disk_service.download key do |chunk|
- response.stream.write chunk
- end
+ serve_file disk_service.path_for(key), content_type: params[:content_type], disposition: params[:disposition]
else
head :not_found
end
- ensure
- response.stream.close
end
def update
@@ -32,13 +23,9 @@ class ActiveStorage::DiskController < ActiveStorage::BaseController
else
head :unprocessable_entity
end
- else
- head :not_found
end
rescue ActiveStorage::IntegrityError
head :unprocessable_entity
- ensure
- response.stream.close
end
private
@@ -51,6 +38,20 @@ class ActiveStorage::DiskController < ActiveStorage::BaseController
ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key)
end
+ def serve_file(path, content_type:, disposition:)
+ Rack::File.new(nil).serving(request, path).tap do |(status, headers, body)|
+ self.status = status
+ self.response_body = body
+
+ headers.each do |name, value|
+ response.headers[name] = value
+ end
+
+ response.headers["Content-Type"] = content_type || DEFAULT_SEND_FILE_TYPE
+ response.headers["Content-Disposition"] = disposition || DEFAULT_SEND_FILE_DISPOSITION
+ end
+ end
+
def decode_verified_token
ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token)