diff --git a/lib/active_storage/blob.rb b/lib/active_storage/blob.rb index 3336c4ebc3..1a15361747 100644 --- a/lib/active_storage/blob.rb +++ b/lib/active_storage/blob.rb @@ -56,8 +56,8 @@ class ActiveStorage::Blob < ActiveRecord::Base service.upload(key, io, checksum: checksum) end - def download - service.download key + def download(&block) + service.download key, &block end diff --git a/lib/active_storage/service/disk_service.rb b/lib/active_storage/service/disk_service.rb index 87fc06c799..7e64e1e909 100644 --- a/lib/active_storage/service/disk_service.rb +++ b/lib/active_storage/service/disk_service.rb @@ -20,8 +20,8 @@ class ActiveStorage::Service::DiskService < ActiveStorage::Service def download(key) if block_given? instrument :streaming_download, key do - File.open(path_for(key)) do |file| - while data = file.binread(64.kilobytes) + File.open(path_for(key), 'rb') do |file| + while data = file.read(64.kilobytes) yield data end end @@ -55,7 +55,7 @@ class ActiveStorage::Service::DiskService < ActiveStorage::Service instrument :url, key do |payload| verified_key_with_expiration = ActiveStorage::VerifiedKeyWithExpiration.encode(key, expires_in: expires_in) - generated_url = + generated_url = if defined?(Rails) && defined?(Rails.application) Rails.application.routes.url_helpers.rails_disk_blob_path(verified_key_with_expiration, disposition: disposition, filename: filename) else @@ -63,7 +63,7 @@ class ActiveStorage::Service::DiskService < ActiveStorage::Service end payload[:url] = generated_url - + generated_url end end diff --git a/test/blob_test.rb b/test/blob_test.rb index 60cf5426a8..cf27d59348 100644 --- a/test/blob_test.rb +++ b/test/blob_test.rb @@ -12,6 +12,19 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase assert_equal Digest::MD5.base64digest(data), blob.checksum end + test "download yields chunks" do + blob = create_blob data: 'a' * 75.kilobytes + chunks = [] + + blob.download do |chunk| + chunks << chunk + end + + assert_equal 2, chunks.size + assert_equal 'a' * 64.kilobytes, chunks.first + assert_equal 'a' * 11.kilobytes, chunks.second + end + test "urls expiring in 5 minutes" do blob = create_blob