Skip to content

Commit 97d6887

Browse files
Fix direct upload of raw files
1 parent 9de92bc commit 97d6887

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

lib/active_storage/service/cloudinary_service.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ def url_for_direct_upload(key, **options)
7272
instrument :url, key: key do |payload|
7373
options = {:resource_type => resource_type(nil, key)}.merge(@options.merge(options.symbolize_keys))
7474
options[:public_id] = public_id_internal(key)
75+
# Provide file format for raw files, since js client does not include original file name.
76+
#
77+
# When the file is uploaded from the server, the request includes original filename. That allows Cloudinary
78+
# to identify file extension and append it to the public id of the file (raw files include file extension
79+
# in their public id, opposed to transformable assets (images/video) that use only basename). When uploading
80+
# through direct upload (client side js), filename is missing, and that leads to inconsistent/broken URLs.
81+
# To avoid that, we explicitly pass file format in options.
82+
options[:format] = ext_for_file(key) if options[:resource_type] == "raw"
7583
options[:context] = {active_storage_key: key}
7684
options.delete(:file)
7785
payload[:url] = api_uri("upload", options)
@@ -174,7 +182,7 @@ def api_uri(action, options)
174182
# @param [string] content_type The content type of the file.
175183
#
176184
# @return [string] The extension of the filename.
177-
def ext_for_file(key, filename, content_type)
185+
def ext_for_file(key, filename = nil, content_type = nil)
178186
if filename.blank?
179187
options = key.respond_to?(:attributes) ? key.attributes : {}
180188
filename = ActiveStorage::Filename.new(options[:filename]) if options.has_key?(:filename)
@@ -200,6 +208,8 @@ def public_id_internal(key)
200208
end
201209

202210
def content_type_to_resource_type(content_type)
211+
return 'image' if content_type.nil?
212+
203213
type, subtype = content_type.split('/')
204214
case type
205215
when 'video', 'audio'

spec/active_storage/service/cloudinary_service_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
url = @service.url_for_direct_upload(key)
3737
expect(url).to include("context=active_storage_key%3D#{key}")
3838
end
39+
40+
it "should include format for raw file" do
41+
key = ActiveStorage::BlobKey.new key: SecureRandom.base58(24), filename: TEST_RAW
42+
url = @service.url_for_direct_upload(key, resource_type: "raw")
43+
expect(url).to include("format=" + File.extname(TEST_RAW).delete('.'))
44+
end
3945
end
4046

4147
it "should support uploading to Cloudinary" do

0 commit comments

Comments
 (0)