activestorage 6.1.4.4 → 7.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +130 -235
- data/MIT-LICENSE +1 -1
- data/README.md +25 -11
- data/app/assets/javascripts/activestorage.esm.js +844 -0
- data/app/assets/javascripts/activestorage.js +257 -376
- data/app/controllers/active_storage/base_controller.rb +1 -10
- data/app/controllers/active_storage/blobs/proxy_controller.rb +14 -4
- data/app/controllers/active_storage/blobs/redirect_controller.rb +6 -4
- data/app/controllers/active_storage/representations/base_controller.rb +5 -1
- data/app/controllers/active_storage/representations/proxy_controller.rb +6 -4
- data/app/controllers/active_storage/representations/redirect_controller.rb +6 -4
- data/app/controllers/concerns/active_storage/set_blob.rb +6 -2
- data/app/controllers/concerns/active_storage/set_current.rb +3 -3
- data/app/controllers/concerns/active_storage/streaming.rb +65 -0
- data/app/javascript/activestorage/ujs.js +1 -1
- data/app/models/active_storage/attachment.rb +36 -3
- data/app/models/active_storage/blob/representable.rb +7 -5
- data/app/models/active_storage/blob.rb +26 -27
- data/app/models/active_storage/current.rb +12 -2
- data/app/models/active_storage/preview.rb +6 -4
- data/app/models/active_storage/record.rb +1 -1
- data/app/models/active_storage/variant.rb +3 -6
- data/app/models/active_storage/variant_record.rb +2 -0
- data/app/models/active_storage/variant_with_record.rb +9 -5
- data/app/models/active_storage/variation.rb +2 -2
- data/config/routes.rb +10 -10
- data/db/migrate/20170806125915_create_active_storage_tables.rb +29 -8
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +15 -2
- data/lib/active_storage/analyzer/audio_analyzer.rb +65 -0
- data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +39 -0
- data/lib/active_storage/analyzer/image_analyzer/vips.rb +49 -0
- data/lib/active_storage/analyzer/image_analyzer.rb +2 -30
- data/lib/active_storage/analyzer/video_analyzer.rb +26 -11
- data/lib/active_storage/analyzer.rb +8 -4
- data/lib/active_storage/attached/changes/create_many.rb +7 -3
- data/lib/active_storage/attached/changes/create_one.rb +1 -1
- data/lib/active_storage/attached/changes/create_one_of_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_one.rb +1 -1
- data/lib/active_storage/attached/changes/detach_many.rb +18 -0
- data/lib/active_storage/attached/changes/detach_one.rb +24 -0
- data/lib/active_storage/attached/changes/purge_many.rb +27 -0
- data/lib/active_storage/attached/changes/purge_one.rb +27 -0
- data/lib/active_storage/attached/changes.rb +7 -1
- data/lib/active_storage/attached/many.rb +27 -15
- data/lib/active_storage/attached/model.rb +31 -5
- data/lib/active_storage/attached/one.rb +32 -27
- data/lib/active_storage/downloader.rb +2 -2
- data/lib/active_storage/engine.rb +28 -1
- data/lib/active_storage/fixture_set.rb +76 -0
- data/lib/active_storage/gem_version.rb +4 -4
- data/lib/active_storage/previewer.rb +4 -4
- data/lib/active_storage/reflection.rb +12 -2
- data/lib/active_storage/service/azure_storage_service.rb +1 -1
- data/lib/active_storage/service/configurator.rb +1 -1
- data/lib/active_storage/service/disk_service.rb +13 -18
- data/lib/active_storage/service/gcs_service.rb +91 -7
- data/lib/active_storage/service/mirror_service.rb +1 -1
- data/lib/active_storage/service/registry.rb +1 -1
- data/lib/active_storage/service/s3_service.rb +4 -4
- data/lib/active_storage/service.rb +3 -3
- data/lib/active_storage/transformers/image_processing_transformer.rb +1 -1
- data/lib/active_storage/transformers/transformer.rb +1 -1
- data/lib/active_storage.rb +3 -1
- metadata +27 -18
- data/app/controllers/concerns/active_storage/set_headers.rb +0 -12
@@ -1,12 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
gem "google-cloud-storage", "~> 1.11"
|
4
|
+
require "google/apis/iamcredentials_v1"
|
4
5
|
require "google/cloud/storage"
|
5
6
|
|
6
7
|
module ActiveStorage
|
7
8
|
# Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
|
8
9
|
# documentation that applies to all services.
|
9
10
|
class Service::GCSService < Service
|
11
|
+
class MetadataServerError < ActiveStorage::Error; end
|
12
|
+
class MetadataServerNotFoundError < ActiveStorage::Error; end
|
13
|
+
|
10
14
|
def initialize(public: false, **config)
|
11
15
|
@config = config
|
12
16
|
@public = public
|
@@ -19,7 +23,7 @@ module ActiveStorage
|
|
19
23
|
# binary and attachment when the file's content type requires it. The only way to force them is to
|
20
24
|
# store them as object's metadata.
|
21
25
|
content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
|
22
|
-
bucket.create_file(io, key, md5: checksum, content_type: content_type, content_disposition: content_disposition)
|
26
|
+
bucket.create_file(io, key, md5: checksum, cache_control: @config[:cache_control], content_type: content_type, content_disposition: content_disposition)
|
23
27
|
rescue Google::Cloud::InvalidArgumentError
|
24
28
|
raise ActiveStorage::IntegrityError
|
25
29
|
end
|
@@ -84,7 +88,31 @@ module ActiveStorage
|
|
84
88
|
|
85
89
|
def url_for_direct_upload(key, expires_in:, checksum:, **)
|
86
90
|
instrument :url, key: key do |payload|
|
87
|
-
|
91
|
+
headers = {}
|
92
|
+
version = :v2
|
93
|
+
|
94
|
+
if @config[:cache_control].present?
|
95
|
+
headers["Cache-Control"] = @config[:cache_control]
|
96
|
+
# v2 signing doesn't support non `x-goog-` headers. Only switch to v4 signing
|
97
|
+
# if necessary for back-compat; v4 limits the expiration of the URL to 7 days
|
98
|
+
# whereas v2 has no limit
|
99
|
+
version = :v4
|
100
|
+
end
|
101
|
+
|
102
|
+
args = {
|
103
|
+
content_md5: checksum,
|
104
|
+
expires: expires_in,
|
105
|
+
headers: headers,
|
106
|
+
method: "PUT",
|
107
|
+
version: version,
|
108
|
+
}
|
109
|
+
|
110
|
+
if @config[:iam]
|
111
|
+
args[:issuer] = issuer
|
112
|
+
args[:signer] = signer
|
113
|
+
end
|
114
|
+
|
115
|
+
generated_url = bucket.signed_url(key, **args)
|
88
116
|
|
89
117
|
payload[:url] = generated_url
|
90
118
|
|
@@ -95,15 +123,31 @@ module ActiveStorage
|
|
95
123
|
def headers_for_direct_upload(key, checksum:, filename: nil, disposition: nil, **)
|
96
124
|
content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
|
97
125
|
|
98
|
-
{ "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
126
|
+
headers = { "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
127
|
+
|
128
|
+
if @config[:cache_control].present?
|
129
|
+
headers["Cache-Control"] = @config[:cache_control]
|
130
|
+
end
|
131
|
+
|
132
|
+
headers
|
99
133
|
end
|
100
134
|
|
101
135
|
private
|
102
136
|
def private_url(key, expires_in:, filename:, content_type:, disposition:, **)
|
103
|
-
|
104
|
-
|
105
|
-
|
137
|
+
args = {
|
138
|
+
expires: expires_in,
|
139
|
+
query: {
|
140
|
+
"response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
|
141
|
+
"response-content-type" => content_type
|
142
|
+
}
|
106
143
|
}
|
144
|
+
|
145
|
+
if @config[:iam]
|
146
|
+
args[:issuer] = issuer
|
147
|
+
args[:signer] = signer
|
148
|
+
end
|
149
|
+
|
150
|
+
file_for(key).signed_url(**args)
|
107
151
|
end
|
108
152
|
|
109
153
|
def public_url(key, **)
|
@@ -137,7 +181,47 @@ module ActiveStorage
|
|
137
181
|
end
|
138
182
|
|
139
183
|
def client
|
140
|
-
@client ||= Google::Cloud::Storage.new(**config.except(:bucket))
|
184
|
+
@client ||= Google::Cloud::Storage.new(**config.except(:bucket, :cache_control, :iam, :gsa_email))
|
185
|
+
end
|
186
|
+
|
187
|
+
def issuer
|
188
|
+
@issuer ||= if @config[:gsa_email]
|
189
|
+
@config[:gsa_email]
|
190
|
+
else
|
191
|
+
uri = URI.parse("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email")
|
192
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
193
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
194
|
+
request["Metadata-Flavor"] = "Google"
|
195
|
+
|
196
|
+
begin
|
197
|
+
response = http.request(request)
|
198
|
+
rescue SocketError
|
199
|
+
raise MetadataServerNotFoundError
|
200
|
+
end
|
201
|
+
|
202
|
+
if response.is_a?(Net::HTTPSuccess)
|
203
|
+
response.body
|
204
|
+
else
|
205
|
+
raise MetadataServerError
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def signer
|
211
|
+
# https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Project.html#signed_url-instance_method
|
212
|
+
lambda do |string_to_sign|
|
213
|
+
iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
|
214
|
+
|
215
|
+
scopes = ["https://www.googleapis.com/auth/iam"]
|
216
|
+
iam_client.authorization = Google::Auth.get_application_default(scopes)
|
217
|
+
|
218
|
+
request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
|
219
|
+
payload: string_to_sign
|
220
|
+
)
|
221
|
+
resource = "projects/-/serviceAccounts/#{issuer}"
|
222
|
+
response = iam_client.sign_service_account_blob(resource, request)
|
223
|
+
response.signed_blob
|
224
|
+
end
|
141
225
|
end
|
142
226
|
end
|
143
227
|
end
|
@@ -17,7 +17,7 @@ module ActiveStorage
|
|
17
17
|
:url_for_direct_upload, :headers_for_direct_upload, :path_for, to: :primary
|
18
18
|
|
19
19
|
# Stitch together from named services.
|
20
|
-
def self.build(primary:, mirrors:, name:, configurator:, **options)
|
20
|
+
def self.build(primary:, mirrors:, name:, configurator:, **options) # :nodoc:
|
21
21
|
new(
|
22
22
|
primary: configurator.build(primary),
|
23
23
|
mirrors: mirrors.collect { |mirror_name| configurator.build mirror_name }
|
@@ -96,14 +96,14 @@ module ActiveStorage
|
|
96
96
|
end
|
97
97
|
|
98
98
|
private
|
99
|
-
def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
|
99
|
+
def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
|
100
100
|
object_for(key).presigned_url :get, expires_in: expires_in.to_i,
|
101
101
|
response_content_disposition: content_disposition_with(type: disposition, filename: filename),
|
102
|
-
response_content_type: content_type
|
102
|
+
response_content_type: content_type, **client_opts
|
103
103
|
end
|
104
104
|
|
105
|
-
def public_url(key, **)
|
106
|
-
object_for(key).public_url
|
105
|
+
def public_url(key, **client_opts)
|
106
|
+
object_for(key).public_url(**client_opts)
|
107
107
|
end
|
108
108
|
|
109
109
|
|
@@ -35,8 +35,8 @@ module ActiveStorage
|
|
35
35
|
# can configure the service to use like this:
|
36
36
|
#
|
37
37
|
# ActiveStorage::Blob.service = ActiveStorage::Service.configure(
|
38
|
-
# :
|
39
|
-
# root: Pathname("/foo/
|
38
|
+
# :local,
|
39
|
+
# { local: {service: "Disk", root: Pathname("/tmp/foo/storage") } }
|
40
40
|
# )
|
41
41
|
class Service
|
42
42
|
extend ActiveSupport::Autoload
|
@@ -57,7 +57,7 @@ module ActiveStorage
|
|
57
57
|
# Passes the configurator and all of the service's config as keyword args.
|
58
58
|
#
|
59
59
|
# See MirrorService for an example.
|
60
|
-
def build(configurator:, name:, service: nil, **service_config)
|
60
|
+
def build(configurator:, name:, service: nil, **service_config) # :nodoc:
|
61
61
|
new(**service_config).tap do |service_instance|
|
62
62
|
service_instance.name = name
|
63
63
|
end
|
@@ -31,7 +31,7 @@ module ActiveStorage
|
|
31
31
|
if name.to_s == "combine_options"
|
32
32
|
raise ArgumentError, <<~ERROR.squish
|
33
33
|
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
34
|
-
as it always generates a single
|
34
|
+
as it always generates a single command.
|
35
35
|
ERROR
|
36
36
|
end
|
37
37
|
|
@@ -31,7 +31,7 @@ module ActiveStorage
|
|
31
31
|
private
|
32
32
|
# Returns an open Tempfile containing a transformed image in the given +format+.
|
33
33
|
# All subclasses implement this method.
|
34
|
-
def process(file, format:)
|
34
|
+
def process(file, format:) # :doc:
|
35
35
|
raise NotImplementedError
|
36
36
|
end
|
37
37
|
end
|
data/lib/active_storage.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2017-
|
4
|
+
# Copyright (c) 2017-2021 David Heinemeier Hansson, Basecamp
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -37,6 +37,7 @@ module ActiveStorage
|
|
37
37
|
extend ActiveSupport::Autoload
|
38
38
|
|
39
39
|
autoload :Attached
|
40
|
+
autoload :FixtureSet
|
40
41
|
autoload :Service
|
41
42
|
autoload :Previewer
|
42
43
|
autoload :Analyzer
|
@@ -59,6 +60,7 @@ module ActiveStorage
|
|
59
60
|
mattr_accessor :content_types_allowed_inline, default: []
|
60
61
|
|
61
62
|
mattr_accessor :service_urls_expire_in, default: 5.minutes
|
63
|
+
mattr_accessor :urls_expire_in
|
62
64
|
|
63
65
|
mattr_accessor :routes_prefix, default: "/rails/active_storage"
|
64
66
|
mattr_accessor :draw_routes, default: true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.0.alpha1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 7.0.0.alpha1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 7.0.0.alpha1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 7.0.0.alpha1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activejob
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 7.0.0.alpha1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 7.0.0.alpha1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 7.0.0.alpha1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 7.0.0.alpha1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: marcel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- CHANGELOG.md
|
104
104
|
- MIT-LICENSE
|
105
105
|
- README.md
|
106
|
+
- app/assets/javascripts/activestorage.esm.js
|
106
107
|
- app/assets/javascripts/activestorage.js
|
107
108
|
- app/controllers/active_storage/base_controller.rb
|
108
109
|
- app/controllers/active_storage/blobs/proxy_controller.rb
|
@@ -115,7 +116,7 @@ files:
|
|
115
116
|
- app/controllers/concerns/active_storage/file_server.rb
|
116
117
|
- app/controllers/concerns/active_storage/set_blob.rb
|
117
118
|
- app/controllers/concerns/active_storage/set_current.rb
|
118
|
-
- app/controllers/concerns/active_storage/
|
119
|
+
- app/controllers/concerns/active_storage/streaming.rb
|
119
120
|
- app/javascript/activestorage/blob_record.js
|
120
121
|
- app/javascript/activestorage/blob_upload.js
|
121
122
|
- app/javascript/activestorage/direct_upload.js
|
@@ -148,7 +149,10 @@ files:
|
|
148
149
|
- db/update_migrate/20191206030411_create_active_storage_variant_records.rb
|
149
150
|
- lib/active_storage.rb
|
150
151
|
- lib/active_storage/analyzer.rb
|
152
|
+
- lib/active_storage/analyzer/audio_analyzer.rb
|
151
153
|
- lib/active_storage/analyzer/image_analyzer.rb
|
154
|
+
- lib/active_storage/analyzer/image_analyzer/image_magick.rb
|
155
|
+
- lib/active_storage/analyzer/image_analyzer/vips.rb
|
152
156
|
- lib/active_storage/analyzer/null_analyzer.rb
|
153
157
|
- lib/active_storage/analyzer/video_analyzer.rb
|
154
158
|
- lib/active_storage/attached.rb
|
@@ -158,12 +162,17 @@ files:
|
|
158
162
|
- lib/active_storage/attached/changes/create_one_of_many.rb
|
159
163
|
- lib/active_storage/attached/changes/delete_many.rb
|
160
164
|
- lib/active_storage/attached/changes/delete_one.rb
|
165
|
+
- lib/active_storage/attached/changes/detach_many.rb
|
166
|
+
- lib/active_storage/attached/changes/detach_one.rb
|
167
|
+
- lib/active_storage/attached/changes/purge_many.rb
|
168
|
+
- lib/active_storage/attached/changes/purge_one.rb
|
161
169
|
- lib/active_storage/attached/many.rb
|
162
170
|
- lib/active_storage/attached/model.rb
|
163
171
|
- lib/active_storage/attached/one.rb
|
164
172
|
- lib/active_storage/downloader.rb
|
165
173
|
- lib/active_storage/engine.rb
|
166
174
|
- lib/active_storage/errors.rb
|
175
|
+
- lib/active_storage/fixture_set.rb
|
167
176
|
- lib/active_storage/gem_version.rb
|
168
177
|
- lib/active_storage/log_subscriber.rb
|
169
178
|
- lib/active_storage/previewer.rb
|
@@ -188,10 +197,10 @@ licenses:
|
|
188
197
|
- MIT
|
189
198
|
metadata:
|
190
199
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
191
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
192
|
-
documentation_uri: https://api.rubyonrails.org/
|
200
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.0.alpha1/activestorage/CHANGELOG.md
|
201
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.0.alpha1/
|
193
202
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
194
|
-
source_code_uri: https://github.com/rails/rails/tree/
|
203
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/activestorage
|
195
204
|
post_install_message:
|
196
205
|
rdoc_options: []
|
197
206
|
require_paths:
|
@@ -200,14 +209,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
209
|
requirements:
|
201
210
|
- - ">="
|
202
211
|
- !ruby/object:Gem::Version
|
203
|
-
version: 2.
|
212
|
+
version: 2.7.0
|
204
213
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
214
|
requirements:
|
206
|
-
- - "
|
215
|
+
- - ">"
|
207
216
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
217
|
+
version: 1.3.1
|
209
218
|
requirements: []
|
210
|
-
rubygems_version: 3.
|
219
|
+
rubygems_version: 3.1.6
|
211
220
|
signing_key:
|
212
221
|
specification_version: 4
|
213
222
|
summary: Local and cloud file storage framework.
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveStorage::SetHeaders #:nodoc:
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
private
|
7
|
-
def set_content_headers_from(blob)
|
8
|
-
response.headers["Content-Type"] = blob.content_type_for_serving
|
9
|
-
response.headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format \
|
10
|
-
disposition: blob.forced_disposition_for_serving || params[:disposition] || "inline", filename: blob.filename.sanitized
|
11
|
-
end
|
12
|
-
end
|