aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage
diff options
context:
space:
mode:
Diffstat (limited to 'activestorage')
-rw-r--r--activestorage/activestorage.gemspec3
-rw-r--r--activestorage/app/models/active_storage/attachment.rb2
-rw-r--r--activestorage/app/models/active_storage/blob.rb15
-rw-r--r--activestorage/lib/active_storage.rb26
-rw-r--r--activestorage/lib/active_storage/analyzer.rb4
-rw-r--r--activestorage/lib/active_storage/downloader.rb29
-rw-r--r--activestorage/lib/active_storage/engine.rb40
-rw-r--r--activestorage/lib/active_storage/previewer.rb8
-rw-r--r--activestorage/lib/active_storage/service.rb6
-rw-r--r--activestorage/test/models/blob_test.rb8
10 files changed, 78 insertions, 63 deletions
diff --git a/activestorage/activestorage.gemspec b/activestorage/activestorage.gemspec
index 34029ac8ad..0ae2dcdd3e 100644
--- a/activestorage/activestorage.gemspec
+++ b/activestorage/activestorage.gemspec
@@ -28,7 +28,8 @@ Gem::Specification.new do |s|
# NOTE: Please read our dependency guidelines before updating versions:
# https://edgeguides.rubyonrails.org/security.html#dependency-management-and-cves
- s.add_dependency "actionpack", version
+ s.add_dependency "actionpack", version
+ s.add_dependency "activejob", version
s.add_dependency "activerecord", version
s.add_dependency "marcel", "~> 0.3.1"
diff --git a/activestorage/app/models/active_storage/attachment.rb b/activestorage/app/models/active_storage/attachment.rb
index 13758d9179..874ba80ca8 100644
--- a/activestorage/app/models/active_storage/attachment.rb
+++ b/activestorage/app/models/active_storage/attachment.rb
@@ -46,3 +46,5 @@ class ActiveStorage::Attachment < ActiveRecord::Base
record.attachment_reflections[name]&.options[:dependent]
end
end
+
+ActiveSupport.run_load_hooks :active_storage_attachment, ActiveStorage::Attachment
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb
index 6ca7d49bc1..4da1605448 100644
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -29,7 +29,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
has_secure_token :key
store :metadata, accessors: [ :analyzed, :identified ], coder: ActiveRecord::Coders::JSON
- class_attribute :service
+ class_attribute :service, default: ActiveStorage.service
has_many :attachments
@@ -193,17 +193,18 @@ class ActiveStorage::Blob < ActiveRecord::Base
#
# The tempfile's name is prefixed with +ActiveStorage-+ and the blob's ID. Its extension matches that of the blob.
#
- # By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tempdir:+ to create it in a different directory:
+ # By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tmpdir:+ to create it in a different directory:
#
- # blob.open(tempdir: "/path/to/tmp") do |file|
+ # blob.open(tmpdir: "/path/to/tmp") do |file|
# # ...
# end
#
# The tempfile is automatically closed and unlinked after the given block is executed.
#
# Raises ActiveStorage::IntegrityError if the downloaded data does not match the blob's checksum.
- def open(tempdir: nil, &block)
- ActiveStorage::Downloader.new(self, tempdir: tempdir).download_blob_to_tempfile(&block)
+ def open(tmpdir: nil, &block)
+ service.open key, checksum: checksum,
+ name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ], tmpdir: tmpdir, &block
end
@@ -272,6 +273,6 @@ class ActiveStorage::Blob < ActiveRecord::Base
{ content_type: content_type }
end
end
-
- ActiveSupport.run_load_hooks(:active_storage_blob, self)
end
+
+ActiveSupport.run_load_hooks :active_storage_blob, ActiveStorage::Blob
diff --git a/activestorage/lib/active_storage.rb b/activestorage/lib/active_storage.rb
index 5c5da551ae..c00c9f8037 100644
--- a/activestorage/lib/active_storage.rb
+++ b/activestorage/lib/active_storage.rb
@@ -41,19 +41,25 @@ module ActiveStorage
autoload :Previewer
autoload :Analyzer
- mattr_accessor :logger
- mattr_accessor :verifier
- mattr_accessor :queues, default: {}
- mattr_accessor :previewers, default: []
- mattr_accessor :analyzers, default: []
+ mattr_accessor :service_configurations, default: {}
+ mattr_accessor :service
+
+ mattr_accessor :queues, default: {}
+ mattr_accessor :previewers, default: []
+ mattr_accessor :analyzers, default: []
mattr_accessor :variant_processor, default: :mini_magick
- mattr_accessor :paths, default: {}
- mattr_accessor :variable_content_types, default: []
+ mattr_accessor :paths, default: {}
+
+ mattr_accessor :variable_content_types, default: []
mattr_accessor :content_types_to_serve_as_binary, default: []
- mattr_accessor :content_types_allowed_inline, default: []
- mattr_accessor :binary_content_type, default: "application/octet-stream"
+ mattr_accessor :content_types_allowed_inline, default: []
+ mattr_accessor :binary_content_type, default: "application/octet-stream"
+
mattr_accessor :service_urls_expire_in, default: 5.minutes
- mattr_accessor :routes_prefix, default: "/rails/active_storage"
+ mattr_accessor :routes_prefix, default: "/rails/active_storage"
+
+ mattr_accessor :logger
+ mattr_accessor :verifier
module Transformers
extend ActiveSupport::Autoload
diff --git a/activestorage/lib/active_storage/analyzer.rb b/activestorage/lib/active_storage/analyzer.rb
index caa25418a5..26414ffbc2 100644
--- a/activestorage/lib/active_storage/analyzer.rb
+++ b/activestorage/lib/active_storage/analyzer.rb
@@ -24,14 +24,14 @@ module ActiveStorage
private
# Downloads the blob to a tempfile on disk. Yields the tempfile.
def download_blob_to_tempfile(&block) #:doc:
- blob.open tempdir: tempdir, &block
+ blob.open tmpdir: tmpdir, &block
end
def logger #:doc:
ActiveStorage.logger
end
- def tempdir #:doc:
+ def tmpdir #:doc:
Dir.tmpdir
end
end
diff --git a/activestorage/lib/active_storage/downloader.rb b/activestorage/lib/active_storage/downloader.rb
index 87be6efb05..4d7e832af5 100644
--- a/activestorage/lib/active_storage/downloader.rb
+++ b/activestorage/lib/active_storage/downloader.rb
@@ -2,24 +2,23 @@
module ActiveStorage
class Downloader #:nodoc:
- def initialize(blob, tempdir: nil)
- @blob = blob
- @tempdir = tempdir
+ attr_reader :service
+
+ def initialize(service)
+ @service = service
end
- def download_blob_to_tempfile
- open_tempfile do |file|
- download_blob_to file
- verify_integrity_of file
+ def open(key, checksum:, name: "ActiveStorage-", tmpdir: nil)
+ open_tempfile(name, tmpdir) do |file|
+ download key, file
+ verify_integrity_of file, checksum: checksum
yield file
end
end
private
- attr_reader :blob, :tempdir
-
- def open_tempfile
- file = Tempfile.open([ "ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter ], tempdir)
+ def open_tempfile(name, tmpdir = nil)
+ file = Tempfile.open(name, tmpdir)
begin
yield file
@@ -28,15 +27,15 @@ module ActiveStorage
end
end
- def download_blob_to(file)
+ def download(key, file)
file.binmode
- blob.download { |chunk| file.write(chunk) }
+ service.download(key) { |chunk| file.write(chunk) }
file.flush
file.rewind
end
- def verify_integrity_of(file)
- unless Digest::MD5.file(file).base64digest == blob.checksum
+ def verify_integrity_of(file, checksum:)
+ unless Digest::MD5.file(file).base64digest == checksum
raise ActiveStorage::IntegrityError
end
end
diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb
index 384e6ebfa6..b27a027f3a 100644
--- a/activestorage/lib/active_storage/engine.rb
+++ b/activestorage/lib/active_storage/engine.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
require "rails"
+require "action_controller/railtie"
+require "active_job/railtie"
+require "active_record/railtie"
+
require "active_storage"
require "active_storage/previewer/poppler_pdf_previewer"
@@ -91,25 +95,25 @@ module ActiveStorage
end
initializer "active_storage.services" do
- ActiveSupport.on_load(:active_storage_blob) do
- if config_choice = Rails.configuration.active_storage.service
- configs = Rails.configuration.active_storage.service_configurations ||= begin
- config_file = Pathname.new(Rails.root.join("config/storage.yml"))
- raise("Couldn't find Active Storage configuration in #{config_file}") unless config_file.exist?
-
- require "yaml"
- require "erb"
-
- YAML.load(ERB.new(config_file.read).result) || {}
- rescue Psych::SyntaxError => e
- raise "YAML syntax error occurred while parsing #{config_file}. " \
- "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
- "Error: #{e.message}"
- end
-
- ActiveStorage::Blob.service =
+ config.after_initialize do |app|
+ ActiveStorage.service_configurations = begin
+ config_file = Pathname.new(Rails.root.join("config/storage.yml"))
+ raise("Couldn't find Active Storage configuration in #{config_file}") unless config_file.exist?
+
+ require "yaml"
+ require "erb"
+
+ YAML.load(ERB.new(config_file.read).result) || {}
+ rescue Psych::SyntaxError => e
+ raise "YAML syntax error occurred while parsing #{config_file}. " \
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
+ "Error: #{e.message}"
+ end
+
+ if global_service_name = app.config.active_storage.service
+ ActiveStorage.service =
begin
- ActiveStorage::Service.configure config_choice, configs
+ ActiveStorage::Service.configure(global_service_name)
rescue => e
raise e, "Cannot load `Rails.config.active_storage.service`:\n#{e.message}", e.backtrace
end
diff --git a/activestorage/lib/active_storage/previewer.rb b/activestorage/lib/active_storage/previewer.rb
index 95a041fd16..af6bcadd4c 100644
--- a/activestorage/lib/active_storage/previewer.rb
+++ b/activestorage/lib/active_storage/previewer.rb
@@ -26,7 +26,7 @@ module ActiveStorage
private
# Downloads the blob to a tempfile on disk. Yields the tempfile.
def download_blob_to_tempfile(&block) #:doc:
- blob.open tempdir: tempdir, &block
+ blob.open tmpdir: tmpdir, &block
end
# Executes a system command, capturing its binary output in a tempfile. Yields the tempfile.
@@ -42,7 +42,7 @@ module ActiveStorage
# end
# end
#
- # The output tempfile is opened in the directory returned by #tempdir.
+ # The output tempfile is opened in the directory returned by #tmpdir.
def draw(*argv) #:doc:
open_tempfile do |file|
instrument :preview, key: blob.key do
@@ -54,7 +54,7 @@ module ActiveStorage
end
def open_tempfile
- tempfile = Tempfile.open("ActiveStorage-", tempdir)
+ tempfile = Tempfile.open("ActiveStorage-", tmpdir)
begin
yield tempfile
@@ -77,7 +77,7 @@ module ActiveStorage
ActiveStorage.logger
end
- def tempdir #:doc:
+ def tmpdir #:doc:
Dir.tmpdir
end
end
diff --git a/activestorage/lib/active_storage/service.rb b/activestorage/lib/active_storage/service.rb
index c18fccbb1d..f0d04153a1 100644
--- a/activestorage/lib/active_storage/service.rb
+++ b/activestorage/lib/active_storage/service.rb
@@ -45,7 +45,7 @@ module ActiveStorage
# Configure an Active Storage service by name from a set of configurations,
# typically loaded from a YAML file. The Active Storage engine uses this
# to set the global Active Storage service when the app boots.
- def configure(service_name, configurations)
+ def configure(service_name, configurations = ActiveStorage.service_configurations)
Configurator.build(service_name, configurations)
end
@@ -82,6 +82,10 @@ module ActiveStorage
raise NotImplementedError
end
+ def open(*args, &block)
+ ActiveStorage::Downloader.new(self).open(*args, &block)
+ end
+
# Delete the file at the +key+.
def delete(key)
raise NotImplementedError
diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb
index 54cf9e2b8a..b7b37bacf5 100644
--- a/activestorage/test/models/blob_test.rb
+++ b/activestorage/test/models/blob_test.rb
@@ -104,14 +104,12 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
end
end
- test "open in a custom tempdir" do
- tempdir = Dir.mktmpdir
-
- create_file_blob(filename: "racecar.jpg").open(tempdir: tempdir) do |file|
+ test "open in a custom tmpdir" do
+ create_file_blob(filename: "racecar.jpg").open(tmpdir: tmpdir = Dir.mktmpdir) do |file|
assert file.binmode?
assert_equal 0, file.pos
assert_match(/\.jpg\z/, file.path)
- assert file.path.starts_with?(tempdir)
+ assert file.path.starts_with?(tmpdir)
assert_equal file_fixture("racecar.jpg").binread, file.read, "Expected downloaded file to match fixture file"
end
end