diff options
author | George Claghorn <george@basecamp.com> | 2018-07-15 19:58:14 -0400 |
---|---|---|
committer | George Claghorn <george@basecamp.com> | 2018-07-15 19:58:14 -0400 |
commit | 390097531bd17369f05a23eba58c37b850ac95dd (patch) | |
tree | b2dfaf535680ae6ff94c6fb7ed441b1d348e397a /activestorage/app/controllers/active_storage | |
parent | 5a71a773eab626319d30f35402b9595a26bfe64e (diff) | |
download | rails-390097531bd17369f05a23eba58c37b850ac95dd.tar.gz rails-390097531bd17369f05a23eba58c37b850ac95dd.tar.bz2 rails-390097531bd17369f05a23eba58c37b850ac95dd.zip |
Support HTTP Range downloads from disk
Closes #32193.
Diffstat (limited to 'activestorage/app/controllers/active_storage')
-rw-r--r-- | activestorage/app/controllers/active_storage/disk_controller.rb | 29 |
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) |